这特别针对解析十六进制字节,但这里有一个更普遍的问题。
假设我有一个正则表达式r
,例如\\s*([0-9A-Fa-f]{2})\\s*
(可选空格,我感兴趣的2个十六进制数字,以及可选空格)。
如果我想用这个正则表达式解析字符串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工具做到这一点?
答案 0 :(得分:3)
我认为这是java.util.Scanner
的用例。您可以使用next(String)
或next(Pattern)
来发现下一个令牌是否与您的正则表达式匹配。
我没有编译器方便,但我认为它会是这样的:
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
}
答案 1 :(得分:2)
另一种选择是使用正则表达式匹配器和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 );
}
......或者其他什么。 lookingAt()必须从当前位置开始,因此匹配必须都是连续的。要捕获的唯一错误条件是提前完成,因为这意味着遇到了非十六进制格式的数据。
答案 2 :(得分:2)
您可以通过添加主题来检查完整输入,或者使用matches()
代替contains()
,正则表达式变为:
^(\\s*([0-9A-Fa-f]{2}))+\\s*$
如果此rgeexp匹配,则可以继续并迭代匹配:
\\s*([0-9A-Fa-f]{2})
获取十六进制字节。