使用java正则表达式替换单词但不使用引号

时间:2016-06-13 21:49:00

标签: java regex string replace replaceall

我想用java regex replace替换句子中的单词。

测试字符串为a_b a__b a_bced adbe a_bc_d 'abcd' ''abcd''

如果我想替换以&开头的所有单词以d结束。 我正在使用String.replaceAll("(?i)\\ba[a-zA-Z0-9_.]*d\\b","temp")

将其替换为a_b a__b temp adbe a_bc_d 'temp' ''temp''

如果我不想在引号中考虑字符串,那么我的正则表达式应该是什么。?

我使用了String.replaceAll("[^'](?i)\\ba[a-zA-Z0-9_.]*d\\b[^']","temp") 它被替换为a_b a__btempadbe temp'abcd' ''abcd''。 它删除了那个词的一个空格。 有没有办法只替换不在引号内的那个字符串?

PS:此String.replaceAll("[^'](?i)\\ba[a-zA-Z0-9_.]*d\\b[^']"," temp ")有一种解决方法。但在某些情况下它失败了。

如果我想替换句子中的单词,那么我的正则表达式应该是什么?我不应该在引号中考虑字符串。? 在此先感谢... !!!

2 个答案:

答案 0 :(得分:1)

您可以使用外观断言:

string = string.replaceAll("(?i)(?<!')\\ba[a-zA-Z0-9_.]*d\\b(?!')", "temp");

RegEx Demo

Read more about lookarounds

答案 1 :(得分:0)

测试目标之前和之后的报价是否错误,因为您无法知道所描述的报价是开头报价还是收盘报价。 (尝试在测试字符串的开头添加引号并测试一个天真的模式,您将看到:'inside'a_outside_d'inside'

知道某些内容是在引号内部还是外部引用的唯一方法是从开头(或从结尾处)检查字符串,但它不那么方便,并且如果引号不是&#39;平衡)。为此,您必须在目标之前描述所有可能的子串,例如:

\G([^a']*+(?:'[^']*'[^a']*|\Ba+[^a']*|a(?!\w*d\b)[^a']*)*+)\ba\w*d\b

细节:

\G  # matches the start of the string or the position after the previous match
(
    [^a']*+ # all that isn't an "a" or a quote
    (?:
        '[^']*'     [^a']* # content between quotes
      |
        \Ba+        [^a']* # "a" not at the start of a word
      |
        a(?!\w*d\b) [^a']* # "a" at the start of a word that doesn't end with "d"
    )*+
) # all that can be before the target in a capture group
\ba\w*d\b # the target

不要忘记在java字符串中转义反斜杠:\ =&gt; \\

要执行替换,您需要参考捕获组1:

$1temp

注意:要处理引号之间的转义引号,请将'[^']*'更改为:'[^\\']*+(?s:\\.[^\\']*)*+'

Demo:点击Java按钮。