Java:replaceAll正则表达式中的古怪

Java:replaceAll正则表达式中的古怪,java,regex,string,Java,Regex,String,我试图用Java操作一个字符串来识别 我在几位在线测试人员中测试了正则表达式,结果它成功了,但当我尝试用Java实现时,它只能识别被下划线包围的文本。我举了一个例子来说明这个问题: private String process(String input) { String processed = input.replaceAll("(\\b|^)\\_(.*)\\_(\\b|$)", "underscore") .replaceAll("(\\b|

我试图用Java操作一个字符串来识别

我在几位在线测试人员中测试了正则表达式,结果它成功了,但当我尝试用Java实现时,它只能识别被下划线包围的文本。我举了一个例子来说明这个问题:

    private String process(String input) {
        String processed = input.replaceAll("(\\b|^)\\_(.*)\\_(\\b|$)", "underscore")
            .replaceAll("(\\b|^)\\*(.*)\\*(\\b|$)", "star")
            .replaceAll("(\\b|^)```(.*)```(\b|$)", "backticks")
            .replaceAll("(\\b|^)\\~(.*)\\~(\\b|$)", "tilde")
            .replaceAll("(\\b|^)\\`(.*)\\`(\\b|$)", "tick")
            .replaceAll("(\\b|^)\\\\\\((.*)\\\\\\)(\\b|$)", "backslashparen")
            .replaceAll("\\*", "%");  // am I matching stars wrong?

    return processed;
}


public void test() {
    String example = "_Text_\n" +
            "*text*\n" +
            "~Text~\n" +
            "`Text`\n" +
            "_Text_\n" +     // is it only matching the first one?
            "``` Text ```\n" +
            "\\(Text\\)\n" +
            "~Text~\n";
    System.out.println(process(example));
}
我希望所有的行都匹配并被替换,但只有第一行匹配。我想知道这是因为它是第一行,所以我抄在中间,它都匹配。然后我想我可能错过了一些匹配特殊字符的东西,所以我添加了剪报以匹配星号,并用百分号替换,结果成功了。我得到的结果如下:

underscore
%text%
~Text~
`Text`
underscore
``` Text ```
\(Text\)
~Text~
你知道我可能遗漏了什么吗


谢谢。

如果您正在使用单词边界,则无需交替匹配锚定,因为单词边界也匹配起始和结束位置。这实际上是冗余匹配:

(?:^|\b)
(?:\b|$)
这两者都可以用
\b
代替

但是查看您的正则表达式,请注意,只有下划线被视为单词字符,
*
~
`
不是单词字符,因此不能在这些字符周围使用
\b
,而应使用
\b
,这与
\b
相反

除此之外,还可以做一些改进,比如使用否定字符类而不是贪婪的
*
,以及删除不必要的组

代码:


在所有正则表达式前面加上
(?m)
前缀,以启用
多行匹配。因此,我使用了您的建议,它按照我的意愿工作,谢谢。但我不明白的是,第一个(强调)在开始和中间的比赛。你能给我指一个参考资料吗?为什么会这样?再次感谢!使用任何边界都没有意义。尝试同时取出^$和\b。不要使用\B因为如果接受
a(
shuld acaept
a_u
不要被边界控制显然你在正则表达式的细微差别上比我强。谢谢你的帮助!快速提问,问号是什么?不会是多余的吗?(和不会是一样的吗?+?)?(
+?
+
效率稍高,因为匹配程序是惰性的或非贪婪的,如果您不想匹配空字符串,那么
+?
将比
*?
效率更高
class MyRegex {
    public static void main (String[] args) {
        String example = "_Text_\n" +
                "*text*\n" +
                "~Text~\n" +
                "`Text`\n" +
                "_Text_\n" +     // is it only matching the first one?
                "``` Text ```\n" +
                "\\(Text\\)\n" +
                "~Text~\n";
        System.out.println(process(example));
    }

    private static String process(String input) {
        String processed = input.replaceAll("\\b_[^_]+_\\b", "underscore")
            .replaceAll("\\B\\*[^*]+\\*\\B", "star")
            .replaceAll("\\B```.+?```\\B", "backticks")
            .replaceAll("\\B~[^~]+~\\B", "tilde")
            .replaceAll("\\B`[^`]+`\\B", "tick")
            .replaceAll("\\B\\\\\\(.*?\\\\\\)\\B", "backslashparen");

        return processed;
    }
}