不能用/(斜杠)做matcher.replaceAll(...)

时间:2013-01-01 20:09:10

标签: java regex pattern-matching

我收到来自其他程序的消息,其中一些字符被更改:

\n(输入) - > #

(哈希)# - > \#

\ - > \\\\

当我试图用我的代码来扭转这些变化时,它可能无法正常工作,可能是那个

  

请注意,替换字符串中的反斜杠()和美元符号($)可能会导致结果与将其视为文字替换字符串时的结果不同。如上所述,美元符号可被视为对捕获的子序列的引用,反斜杠用于替换替换字符串中的文字字符。

这是我的代码:

public String changeChars(final String message) {

    String changedMessage = message;

    changedMessage = changePattern(changedMessage, "[^\\\\][#]", "\n");
    changedMessage = changePattern(changedMessage, "([^\\\\][\\\\#])", "#");
    changedMessage = changePattern(changedMessage, "[\\\\\\\\\\\\\\\\]", "\\\\");

    return changedMessage;
}

private String changePattern(final String message, String patternString, String replaceString) {
    Pattern pattern = Pattern.compile(patternString);
    Matcher matcher = pattern.matcher(message);
    return matcher.replaceAll(replaceString);
}

1 个答案:

答案 0 :(得分:1)

我假设你的编码方法是这样的。

  1. 将所有\替换为\\\\
  2. 标记最初将#标记为\#
  3. 现在,因为我们知道所有最初放置#的{​​{1}}前面都有\,我们可以使用\n标记#。{/ li>

    代码可能类似于

    data = data.replace("\\", "\\\\\\\\");
    data = data.replace("#", "\\#");
    data = data.replace("\n", "#");
    

    要扭转此操作,我们需要从结束开始(表格最后替换)

    • 我们将使用换行#标记替换之前没有\的所有\n(如果我们从第二次替换开始\# - > {{ 1}}我们后来不知道#替换#中的哪个\n
    • 之后,我们可以安全地将\#替换为#(这样我们就可以摆脱原始字符串中没有的额外\,并且不会打扰我们的最后一次更换工序)。
    • 最后我们将\\\\替换为\

    以下是我们如何做到的。

    //your previous regex [^\\\\][#] describes "any character that is not \ and #
    //but since we don't want to include that additional non `\` mark while replacing 
    //we should use negative look-behind mechanism "(?<!prefix)"
    data = data.replaceAll("(?<!\\\\)#", "\n");
    
    //now since we got rid of additional "#" its time to replace `\#` to `#`
    data = data.replace("\\#", "#");
    
    //and lastly `\\\\` to `\`
    data = data.replace("\\\\\\\\", "\\");
    
相关问题