java:使用正则表达式解析重复的子串

时间:2009-12-30 20:37:37

标签: java regex

这特别针对解析十六进制字节,但这里有一个更普遍的问题。

假设我有一个正则表达式r,例如\\s*([0-9A-Fa-f]{2})\\s*(可选空格,我感兴趣的2个十六进制数字,以及可选空格)。

如果我想用这个正则表达式解析字符串s,那么:

  • 如果s可以划分为匹配r的一系列块,我想为每个块做一些事情。 (例如,ff 7c 0903 02BB aC可以这种方式划分。)

  • 如果s无法相应划分,我想检测一下。 (例如00 01 02 hi there ab ff9 0 2 1 0以及Y0 DEADBEEFcafe BABE!都失败了。)

我怎么能用Java的regexp工具做到这一点?

3 个答案:

答案 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})

获取十六进制字节。