java:使用regex解析重复的子字符串
这是专门针对解析十六进制字节的,但这里有一个更一般的问题 假设我有一个regexpjava:使用regex解析重复的子字符串,java,regex,Java,Regex,这是专门针对解析十六进制字节的,但这里有一个更一般的问题 假设我有一个regexpr例如\\s*([0-9A-Fa-f]{2})\\s*(可选空格,我感兴趣的两个十六进制数字和可选空格) 如果我想用这个regexp解析字符串s,那么: 如果可以将s划分为一系列与r匹配的块,我想为每个块做一些事情。(例如,ff 7c 0903 02BB aC可以这样划分。) 如果s不能被相应地分割,我想检测这个。(例如,00 01 02 hi there ab ff和9 0 2 1 0和Y0 DEADBEEF和
r
例如\\s*([0-9A-Fa-f]{2})\\s*
(可选空格,我感兴趣的两个十六进制数字和可选空格)
如果我想用这个regexp解析字符串s
,那么:
- 如果可以将
划分为一系列与s
匹配的块,我想为每个块做一些事情。(例如,r
可以这样划分。)ff 7c 0903 02BB aC
- 如果
不能被相应地分割,我想检测这个。(例如,s
和00 01 02 hi there ab ff
和9 0 2 1 0
和Y0 DEADBEEF
全部失败。)cafe BABE!
如何使用Java的regexp工具来实现这一点?我相信这是一个Java的用例。您可以使用或来发现下一个令牌是否与您的正则表达式匹配 我手边没有编译器,但我想它应该是这样的:
Scanner myScanner = new Scanner(mySource);
// default delimiter is any whitespace, so you don't need to call useDelimiter()
Pattern myPattern = Pattern.compile("\\s*([0-9A-Fa-f]{2})\\s*");
String s = null;
while ((s = myScanner.next(myPattern)) != null) {
// do something with the token
}
另一种选择是使用正则表达式匹配器和lookingAt()方法 比如:
Pattern p = Pattern.compile( "\\s*([0-9A-Fa-f]{2})" );
Matcher m = p.matcher( myString );
int lastEnd = 0;
while( m.lookingAt() ) {
System.out.println( "Hex part:" + m.group(1) );
lastEnd = m.end();
}
if( lastEnd < myString.length() ) {
System.err.println( "Encountered non-hex value at index:" + lastEnd );
}
Pattern p=Pattern.compile(\\s*([0-9A-Fa-f]{2})”;
Matcher m=p.Matcher(myString);
int lastEnd=0;
while(m.lookingAt()){
系统输出打印项次(“六角部分:+m组(1));
lastEnd=m.end();
}
if(lastEnd
……或者别的什么。lookingAt()必须从当前位置开始,因此所有匹配项都必须是连续的。要捕获的唯一错误条件是提前完成,因为这意味着遇到了非十六进制格式的数据。您可以通过添加锚来检查完整的输入,或者使用
匹配()
而不是包含()
,regexp变为:
^(\\s*([0-9A-Fa-f]{2}))+\\s*$
如果此rgeexp匹配,则可以继续并迭代以下匹配项:
\\s*([0-9A-Fa-f]{2})
获取十六进制字节。有趣的是,好的,我如何确保令牌之前/之后/之间没有不匹配的输入?嗯。。。已经有一段时间了,但我认为您必须尝试
hasNext()
和skip()
。我们不打算使用2个regexp,但这肯定是简单明了的。这是迄今为止最好的答案,但您正在考虑的另一种方法是Matcher#find()
contains()
是一个字符串方法,只进行文本搜索。@Alan,谢谢你的评论,我指的是Jakarta ORO方法匹配和contains.neat!我最终手动执行了这种方法(检查前一个end()和当前的start()),不知道lookingAt()。这是不对的lookingAt()
仅匹配匹配器区域的开头,默认情况下,该区域是字符串的开头。您可以通过不断更改区域的起始边界来实现这种方法,但只需将\G
前置到正则表达式并使用find()
就更容易了。实际上,你的代码只是在一个无限循环中不断匹配前两个十六进制数字(如果它匹配任何东西的话),他是对的。我使用lookingAt()实现类似目的的代码每次都会截断字符串。。。这是另一种选择。myString=myString.substring(lastEnd)几乎是免费的。我忘记放了。