我有这个正则表达式
"((\\s{0,2})\\p{XDigit}{2}\\s{0,2})*"
用户可以像这样从字节转储中选择匹配的字符串
上面的选择应该是可能的,但是选择Byte的一半不应该这样
结尾或开头的空格不应该是这样的问题
给定正则表达式的问题是匹配需要太长时间。我能改进什么,问题是什么?
编辑:
所以我为这个案例建立了一个解决方案。我唯一需要检查的是字符串的开头和结尾。删除空格并检查分割字符串的第一个和最后一个元素长度是否为1.我无论如何都要拆分它,因为之后我将它解析为一个字节数组。
String selection = dumpText.getSelectionText();
if (selection.equals(" ") || selection.equals(" ")){
return;
}
//remove spaces at the beginning
while(selection.charAt(0) == ' '){
selection = selection.substring(1);
}
//remove spaces at the end
while(selection.charAt(selection.length()-1) == ' '){
selection = selection.substring(0, selection.length()-1);
}
String[] splitted = selection.split("\\s{1,2}");
if(splitted.length == 0 || splitted[0].length()==1 || splitted[splitted.length-1].length()==1){
return;
}
答案 0 :(得分:3)
当你问一些简单的事情时,基本的字符串比较会更有效率。在这种情况下,您只对前2个和后2个字符感兴趣。
所以你只能测试那些(在验证长度之后):
s.charAt(0) != ' ' && s.charAt(1) == ' '
&& s.charAt(s.length - 1) != ' ' && s.charAt(s.length - 2) == ' '
虽然这不是很花哨,但它会非常快。你只是测试你是否有一个角色然后是一个空格,最后是另一种方式。
这仅适用于基本验证。
答案 1 :(得分:1)
尝试这种模式:
\s{0,2}(?:\p{XDigit}{2}\s{0,2})*
您遇到Catastrophic Backtracking,其中(在这种情况下)您有多种方法无法匹配字符串。
我写的模式基本相同,但应该只有一种方法匹配选择:
\s{0,2}
- 可选的前导空格(?:\p{XDigit}{2}\s{0,2})*
- 一个或多个十六进制对,后面有空格。请注意,此模式可以匹配没有空格的十六进制数字,例如12AB
,但它仍适用于您的用例。
答案 2 :(得分:0)
另一个解决方案,只是检查是否有任何单个字符被空格包围。
/^([a-zA-Z0-9]\s+)|(\s+[a-zA-Z0-9]\s+)|(\s+[a-zA-Z0-9])$/gm
或类似的东西,以便在序列的开头或结尾匹配单个字符
/^([a-zA-Z0-9]\s+)|(\s+[a-zA-Z0-9])$/gm
或者这个,它只返回两个字符出现
/(?:\s*)([a-zA-Z0-9]{2})(?:\s*)/gm
附注:在这种情况下,您可以使用\p{XDigit}
代替[a-za-z0-9]
答案 3 :(得分:0)
我实际上并不会尝试匹配前置空格或尾随空格,并且会使正则表达式像使用单词边界一样简单:
\\b\\p{XDigit}{2}\\b
在Matcher#find
中使用此正则表达式可以单独匹配每个字节序列。