0

所以我需要返回修改后的字符串,它在跳过注释时用另一个令牌替换令牌的第一个实例。这是我正在谈论的一个例子:

This whole quote is one big String
-- I don't want to replace this @@
But I want to replace this @@!

作为一名前 .NET 开发人员,我认为这很容易。我会像这样做一个负面的回顾:

(?<!--.*)@@

但后来我了解到 Java 不能做到这一点。所以在得知花括号没问题后,我尝试了这个:

(?<!--.{0,9001})@@

这并没有引发异常,但它确实与评论中的 @@ 匹配。

当我使用 Java 正则表达式测试器测试这个正则表达式时,它按预期工作。我能想到的唯一一件事就是我使用的是 Java 1.5。Java 1.5 的正则表达式引擎中是否有可能存在错误?假设它确实如此,我如何让 Java 1.5 做我想要它做的事情而不分解我的字符串并重新组装它?

编辑我将 # 更改为 -- 运算符,因为看起来正则表达式会更复杂,有两个字符而不是一个字符。我最初并没有透露我正在修改查询,以避免关于“你不应该那样修改查询!”的题外话讨论。我这样做是有充分理由的。请不要讨论查询修改的良好做法。谢谢

4

2 回答 2

5

你真的不需要negative look-behind这里。没有它你也可以做到。

它会是这样的:

String str = "I don't want to replace this @@";     
str = str.replaceAll("^([^#].*?)@@", "$1");

@@因此,它将字符串中不以 开头的字符串的第一次出现替换#为 before @@。所以,@@被删除。这里replaceAll有效,因为它使用了不情愿的量词- .*?。所以,它会自动停止在第一个@@.


正如@nhahtdh 在评论中正确指出的那样,如果您的评论位于行尾,这可能会失败。所以,你可以使用这个:

String str = "I don't want to # replace this @@";
str = str.replaceAll("^([^#]*?)@@", "$1");

这个适用于任何情况。在给定的示例情况下,它不会替换@@,因为它是注释的一部分。


如果您的评论开头由两个字符表示,则否定字符类将不起作用。你需要negative look-ahead像这样使用:

String str = "This whole quote @@  is one big String -- asdf @@\n" +
             "-- I don't want to replace this @@\n" + 
             "But I want to replace this @@!";
str = str.replaceAll("(?m)^(((?!--).)*?)@@", "$1");

System.out.println(str);

输出:

This whole quote   is one big String -- asdf @@
-- I don't want to replace this @@
But I want to replace this !

(?m)模式的开头用于启用MULTILINE匹配模式,因此^将匹配每一行的开头,而不是整个表达式的开头。

于 2013-02-14T19:50:40.660 回答
0

你可以使用这样的东西:

String string = "This whole quote is one big String\n" +
                "# I don't want to replace this @@\n" +
                "And I also # don't want to replace this @@\n" +
                "But I want to replace this @@!\n" +
                "But not this @@!";

Matcher m =
    Pattern.compile (
        "^((?:[^@#]|@[^@]|#[^\n]*)*)@@", Pattern.MULTILINE).
            matcher (string);

StringBuffer result = new StringBuffer ();
if (m.find ())
    m.appendReplacement (result, "$1FOO");
m.appendTail (result);

System.out.println (result.toString ());
于 2013-02-14T19:58:25.370 回答