java - 多次匹配后视/前视

标签 java regex regex-lookarounds lookbehind

代码:

public static void main(String[] args) {
    String mainTag = "HI";
    String replaceTag = "667";
    String text = "92<HI=/><z==//HIb><cHIhi> ";
    System.out.println(strFormatted(mainTag, replaceTag, text));

    mainTag = "aBc";
    replaceTag = "923";
    text = "<dont replacethis>abcabc< abcabcde >";
    System.out.println(strFormatted(mainTag, replaceTag, text));
}

private static String strFormatted(String mainTag, String replaceTag, String text) {
    return text.replaceAll("(?i)(?<=<)" + mainTag + "(?=.*>)", replaceTag);
}

所以,我想替换mainTag (变量)为replaceTag (变量)内部标签 ( <...> )。

在上面的示例中,我想替换 mainTag HI (不区分大小写)在所有出现的内部 <...>667 ,但我的代码仅替换第一次出现的情况。

示例:

92<HI=/><z==//HIb><cHIhi> 

预期输出:

92<667=/><z==//667b><c667667> 

(mainTag =“HI”,replaceTag =“667”)

<dont replacethis>abcabc<abcabcde>

预期输出:

<dont replacethis>abcabc<923923de>

(mainTag =“aBc”,replaceTag =“923”);

注意:我的代码是错误的,不仅因为他只替换了1次,还因为它只有在“mainTag”接替“<”时才有效,换句话说,lookbehind仅有效对于独特的情况。

最佳答案

你只需要在这里向前看。这个想法是找到所有mainTags ,后面跟着 > ,然后匹配<>对,并替换为 replaceTag 。以下正则表达式可以工作:

text.replaceAll("(?i)" + mainTag + "(?=[^<>]*>(?:[^<>]*<[^<>]*>)*[^<>]*)$", replaceTag);

说明:

(?i)               # Ignore Case
mainTag            # Match mainTag
(?=                # which is followed by
    [^<>]*         # Some 0 or more characters which are not < or >
    >              # Close the bracket (this ensures, mainTag is between closing bracket
    (?:            # Start a group (to match pair of bracket)
        [^<>]*     # non-bracket characters
        <          # Start a bracket 
        [^<>]*     # non-bracket characters
        >          # End the bracket
    )*             # Match the pair 0 or more times.
    [^<>]*         # Non-bracket characters 0 or more times.
)
[^<>]*)$

上面的正则表达式实际上假设括号始终是平衡的。对于不平衡的正则表达式,这可能会产生意想不到的结果。但正则表达式并不是真正适合此类工作的工具。

否则一个简单的正则表达式也可以正常工作:

"(?i)" + mainTag + "(?=[^<>]*>)"

这取决于您的用例。这不用担心平衡括号。您可以先尝试第二个,如果它适合所有场景,那就最好了。

关于java - 多次匹配后视/前视,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36819487/

相关文章:

java注解判断被注解的方法是否执行

Java:我如何知道我的 TableModel 是否有 TableModelListener?

java - 获取 "success"而没有收到任何 GCM 消息

regex - 如何在路径中扩展波浪号 (~)

regex - 用于在字符串的第一个位置匹配 char '*' 的 Perl RegEx

c# - 在 C# Regex 中检索括号之间的字符串

regex - 转为否定前瞻替代方案

Java 8 Lambda 按列表过滤

regex - 通过正则表达式限制文本中的行数

javascript - 在 JavaScript 中,如何将字符串 "aa,bb\\,cc,dd"以逗号分隔,但前提是前一个字符不是反斜杠?