我需要更换所有&在不属于HTML实体的字符串中。因此字符串“This& entites >
&amp; <
”将返回“此&
entites > & <
”
我想出了这个正则表达式模式:“&amp; [a-zA-Z0-9] {2,7}; ”哪个正常。 但是我对正则表达式并不是很熟练,当我测试超过100k迭代的速度时,它比先前使用的方法使用了两倍的时间,没有使用正则表达式。 (但也不是100%工作)。
Testcode:
long time = System.currentTimeMillis();
String reg = "&(?!&#?[a-zA-Z0-9]{2,7};)";
String s="a regex test 1 & 2 1&2 and &_gt; - &_lt;"
for (int i = 0; i < 100000; i++) {test=s.replaceAll(reg, "&");}
System.out.println("Finished in:" + (System.currentTimeMillis() - time) + " milliseconds");
所以问题是,是否有一些明显的方法来优化这个正则表达式以使其更有效?
答案 0 :(得分:6)
s.replaceAll(reg, "&")
每次都在编译正则表达式。编译模式一次将提高性能(在这种情况下约为30%)。
long time = System.currentTimeMillis();
String reg = "&(?!&#?[a-zA-Z0-9]{2,7};)";
Pattern p = Pattern.compile(reg);
String s="a regex test 1 & 2 1&2 and &_gt; - &_lt;";
for (int i = 0; i < 100000; i++) {
String test = p.matcher(s).replaceAll("&");
}
System.out.println("Finished in:" +
(System.currentTimeMillis() - time) + " milliseconds");
答案 1 :(得分:2)
您必须从先前的断言中排除&
。所以试试这个正则表达式:
&(?!#?[a-zA-Z0-9]{2,7};)
或者更确切地说:
&(?!(?:#(?:[xX][0-9a-fA-F]|[0-9]+)|[a-zA-Z]+);)
答案 2 :(得分:1)
使用正则表达式的另一种方法是使用StringEscapeUtils中的Commons Lang。
答案 3 :(得分:0)
我对Java正则表达式类不是很熟悉,但一般来说你可能想要调查零宽度前瞻;在&符之后。
Here is a link描述正面和负面的前瞻