16
回答
java 正则表达式

import java.util.*;
public static void main(String[] args){
          String str = new String("$GPTAX,1,2013201,1,2019,你好!*hh"+"\n");
          //hh是校验和,我想把字符串里     被逗号分隔每组串  都提取出来(但不需要去提取$GPTAX         *hh       \n),可是却运行不出来,代码如下 不知道是不是正则表达式写错了?怎么修改?
         Pattern p = Pattern.compile("\\$[A-Z]{5},([0-5]),(\\d{1,7}),([0-1]),(.{4,}),(.+)\\*(.{2})\\s+");         

         Matcher m = p.matcher(str); 

        if(m.find()){ 
                             System.out.println(m.group(1)); 
                       }
     }
}

<无标签>
举报
风之恋---
发帖于5年前 16回/646阅
共有16个答案 最后回答: 5年前

在电脑上调试过了。

String src = "$GPTAX,1,2013201,1,2019,你好!*hh";
		//加了问号,勉强模式,不管后面是不是换行回车
		Matcher matcher = Pattern.compile("\\$GPTAX,(.*?)\\*hh").matcher(src);
		String strAfterMatched = null;
		if(matcher.find())
			//strAfterMatched = "1,2013201,1,2019,你好!";
			strAfterMatched = matcher.group(1);
		//你懂的
		String[] results = strAfterMatched.split(",");

升级版:

		String src = "$GPTAX,1,2013201,1,2019,你好!*hh<CR><LF>";
		Pattern pattern = Pattern.compile("\\$[A-Z]{5},([0-5]),(\\d{1,7}),([0-1]),(.{4,}?),(.+?)\\*");
		Matcher matcher = pattern.matcher(src);
		while(matcher.find()){
			for(int i=1;i<=matcher.groupCount();i++){
				System.out.println(matcher.group(i));
			}
		}



--- 共有 3 条评论 ---
Timco回复 @风之恋--- : (.*?)\\*hh,括号捕获的就是遇到“*”前的字符了。http://www.jb51.net/tools/zhengze.html#greedyandlazy 5年前 回复
风之恋---\\$GPTAX,(.*?)\\*hh 里的(.*?),如果是数字,英文逗号,汉子,键盘上的特殊符号,也就(.*?)是最简化了吧。 还有一个疑问就是,(.*?)后边的\\*hh是不是也没有意义,如果你说我在后边再写\\s+没意义,我的意思是: (.*?)也会包含 后边的\\*hh,这样你就split的时候,最后一个字符串可能会包含\\*hh吧。。。。当然输出的结果确实没有,所以晕啊。。。 5年前 回复
风之恋---我是不是有些字符有问题,然后 您给改的?要是这样的话,至少我思路没问题。。。。万分感谢啊! 我还有一个问题,在下边引用此答案吧 5年前 回复

[url=file://$[a-z]%7b5%7d

这是什么意思啊。。

--- 共有 5 条评论 ---
freesnow回复 @风之恋--- : 我把你的正则拷下来之后,一共改了三个地方,一个是大S改成小s,一个是第三部分的小括号改成英文的,还有就是第三部分小括号开头的空格去掉,然后就可以匹配了。但是你说你打字有问题,所以后两个我没和你说。再有,你可别告诉我你字符串里就用的<CR><LF>.. 5年前 回复
风之恋---回复 @freesnow : 我改成小写的s了可是还是不能运行。。。。 5年前 回复
freesnow回复 @风之恋--- : 我试了一下,是因为你最后用的\S,应该是小写的s。小写的\s表示空白字符,\S表示非空白字符,匹配回车换行应该是\s 5年前 回复
freesnow我试了一下,是因为你最后用的\S,应该是小写的s。小写的\s表示空白字符,\S表示非空白字符,匹配回车换行应该是\s 5年前 回复
风之恋---输入问题。。。不好意思啊 5年前 回复

感觉楼主没有表达清楚。到底需不需要“$GPTAX”和“*hh<CR><LF>”。

你源代码构造字符串的时候引号都没有,怎么运行出来?

如果要所有以“,”分开的字符串,只需要一句

String[] rs = string.split(",");



--- 共有 1 条评论 ---
风之恋---因为工作电脑 和上网的分开 敲得有些问题了,见谅啊。 不需要“$GPTAX”和“*hh<CR><LF>这两个字符串 5年前 回复

引用来自“Timco”的答案

在电脑上调试过了。

String src = "$GPTAX,1,2013201,1,2019,你好!*hh";
		//加了问号,勉强模式,不管后面是不是换行回车
		Matcher matcher = Pattern.compile("\\$GPTAX,(.*?)\\*hh").matcher(src);
		String strAfterMatched = null;
		if(matcher.find())
			//strAfterMatched = "1,2013201,1,2019,你好!";
			strAfterMatched = matcher.group(1);
		//你懂的
		String[] results = strAfterMatched.split(",");

升级版:

		String src = "$GPTAX,1,2013201,1,2019,你好!*hh<CR><LF>";
		Pattern pattern = Pattern.compile("\\$[A-Z]{5},([0-5]),(\\d{1,7}),([0-1]),(.{4,}?),(.+?)\\*");
		Matcher matcher = pattern.matcher(src);
		while(matcher.find()){
			for(int i=1;i<=matcher.groupCount();i++){
				System.out.println(matcher.group(i));
			}
		}



如果发送:你好!到20139810这张卡号上,内容写到FileInputStream类的(比如定义了这个对象)mInputStream这个对象里了,最后传输到显示器上是$GPTXA,20139810,1,0,你好!*hh 

备注:GPTXA也可以写成其他的好多字符串(就只能写5位)20139810是发送的卡号,逗号之间1可以写0或者1,逗号之间0可以写0或者1,你好!是发送内容,hh是这些字符异或运算的结果有什么简单方法实现这些字符串的拼接么?我就直接那么连接的,可是除了这个例子中的GPTXA外,还有好多条指令比如(GPMSA,GPKHB,...BDTXA,BDMSA,BDKHB...),我那种方法就显得太笨拙了,N种方法一个个写的话 也就很多了  不知道大侠有什么思路 能简化写的代码?

我是这么写的:(简要代码)

public static final String GP = "$GP";

public static final String TAX = "TAX";

public static final String D = ",";

public static final String X = "*P";

public static final String END = "\n";

public static final String zero = "0";

public static final String GP = "$GP";

public static final String one = "1";

public static final String hh = "76";

//定义的常量字符串

mOutputStream.write(GP.getBytes());

mOutputStream.write(GP.getBytes());

mOutputStream.write(GP.getBytes());

mOutputStream.write(TAX.getBytes());

mOutputStream.write(D.getBytes());

mOutputStream.write(number.getBytes("gb2312"));//是从输入框传进来的卡号例如

2013201


mOutputStream.write(D.getBytes());

mOutputStream.write(one.getBytes());

mOutputStream.write(D.getBytes());

mOutputStream.write(zero.getBytes());

mOutputStream.write(D.getBytes());

mOutputStream.write(text.getBytes("gb2312"));//输入框传进来的   你好!

mOutputStream.write(X.getBytes());

mOutputStream.write(hh.getBytes());

mOutputStream.write('\n');

我是这么完成这个发送封装的  有点太臃肿了,所以希望思路上什么的给点指点,当然要代码的话   也可以给你 看

虽然你描述了很多,但是我还是没有看明白。。。

要是可以的话,看能不能给方法传一个枚举类型,作为一个标识 - -

String handle(MsgType type,Object...params) 

--- 共有 4 条评论 ---
风之恋---回复 @Timco : GPTAX,1,2013201,1,2019,你好! 对所有字符(每个8位)执行异或运算(当然在这里边逗号间的每段数据都是可以手动填入的,不过这个格式是固定的)然后最终运行结果将16进制的高四位和低四位转成两个ASCII码字符,我想到的是先把每个字符用Byte存储,然后挨个异或,这样算法又是好臃肿笨拙啊啊。。。。。 能给个方法完成这个过程吗 5年前 回复
Timco回复 @风之恋--- : 正则表达式书写正确的一个简单方法就是,尽量用勉强批判模式。你这里 . 能匹配除换行符外任意字符,所以后面的就白写了。它不会去匹配那个 , 及以后的字符 5年前 回复
风之恋---枚举没看过 一会研究一下下。。。 5年前 回复
风之恋---我的表达式(.{4,}),(.+)比拟的表达式(.{4,}?),(.+?)少两个问号就不能通过了........?有点晕啊,不写的话,应该是只出现一次,为啥就不能通过了....... 5年前 回复

引用来自“freesnow”的答案

[url=file://$[a-z]%7b5%7d

这是什么意思啊。。

String str = "$GPTAX,1,2013201,1,2019,你好!*hh"+"\n";
Pattern p = Pattern.compile("\\$[A-Z]{5},([0-5]),(\\d{1,7}),([0-1]),(.{4,}),(.+)\\*(.{2})\\s+");
Matcher m = pattern.matcher(str);
if(m.find()){

  System.out.println(m.group(5));
}

是这样吧,额可是还是不能运行。。。。

引用来自“Timco”的答案

虽然你描述了很多,但是我还是没有看明白。。。

要是可以的话,看能不能给方法传一个枚举类型,作为一个标识 - -

String handle(MsgType type,Object...params) 

勉强批判 是说 写的尽力符合字符串规则,还是写的模糊?
String str = "$GPICI,1234567,2013201,01891,2,10,1,E,0*F3"+"\n";
Pattern p = Pattern.compile(" \\$[A-Z]{5},(\\d{7}),(\\d*),(\\d*),([0-7]),(\\d*),([1-4]),([EN]),(\\d*)\\*([0-9A-F]{2})\\s+");
Matcher m = pattern.matcher(str);
if(m.find()){
 
  System.out.println(m.group(5));
 }
这个也不输出结果。。。。试了半天
--- 共有 2 条评论 ---
风之恋---回复 @freesnow :嗯,我也奇怪呢,按我写的找不出问题啊,可是 运行就是没有结果...郁闷了 5年前 回复
freesnow勉强匹配是和贪婪匹配对应的,是说*+{n}这些符号尽可能少的匹配,我觉得翻译的不好。。我觉得最奇怪的地方是,我在测试工具上,我上次给你改的和你现在写的都能正确匹配,但你却说没有结果。工作的电脑上没有java环境,打算周末看看呢。 5年前 回复

引用来自“风之恋---”的答案

引用来自“Timco”的答案

虽然你描述了很多,但是我还是没有看明白。。。

要是可以的话,看能不能给方法传一个枚举类型,作为一个标识 - -

String handle(MsgType type,Object...params) 

勉强批判 是说 写的尽力符合字符串规则,还是写的模糊?
String str = "$GPICI,1234567,2013201,01891,2,10,1,E,0*F3"+"\n";
Pattern p = Pattern.compile(" \\$[A-Z]{5},(\\d{7}),(\\d*),(\\d*),([0-7]),(\\d*),([1-4]),([EN]),(\\d*)\\*([0-9A-F]{2})\\s+");
Matcher m = pattern.matcher(str);
if(m.find()){
 
  System.out.println(m.group(5));
 }
这个也不输出结果。。。。试了半天

勉强模式就是尽可能少匹配。

正则只需要关注你想匹配的部分,像你这后面的\\s+,又没打算捕获,没意义。

Pattern.compile("\\$[A-Z]{5},(\\d{7}),(\\d*),(\\d*),([0-7]),(\\d*),([1-4]),([EN]),(\\d*)\\*([0-9A-F]{2})");



--- 共有 1 条评论 ---
风之恋---刚刚又试了了一下 你修改以后的也不行啊。。。 5年前 回复
顶部