【问题标题】:Matches lookbehind / ahead multiple times多次向后/向前匹配
【发布时间】:2016-04-24 05:06:47
【问题描述】:

代码:

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(变量)在标签内(&lt;...&gt;)。

在上面的示例中,我想用667 替换所有inside &lt;...&gt; 中的mainTag HI(不区分大小写),但我的代码只替换了第一个出现。 p>

示例:

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”成功于“

【问题讨论】:

  • 尝试使用代码格式发布此内容(行首有四个空格或将代码包含在反引号中,即')。额外的 \s 使这变得难以理解。
  • 您希望将 HIb 的 hi 更改为 667b,但不要将 hireplacethis 更改为 replacet667s..
  • @rock321987 我添加了更多代码和信息。

标签: java regex lookahead lookbehind


【解决方案1】:

您只需要在此处进行前瞻。这个想法是找到所有的mainTags,然后是&gt;,然后匹配成对的&lt;&gt;,并替换为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 + "(?=[^<>]*>)"

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

【讨论】:

  • 感谢您的回答,但对于第二个示例,它正在替换第一个 (abcabc),但正如我所说,它只能在标签内替换 。
  • @developer033 是的,我更新了正则表达式。有什么东西不见了。它现在应该可以工作了
  • 我打算只建议(?=[^&lt;&gt;]*&gt;) 进行前瞻。我不明白为什么需要其余的,尤其是因为它都是可选的。
  • @AlanMoore 确保括号平衡。否则只是简单的也可以工作
  • @developer033 酷。那我建议你只用第二个。以后很容易调整:)
猜你喜欢
  • 1970-01-01
  • 2023-02-26
  • 1970-01-01
  • 1970-01-01
  • 2021-05-13
  • 2019-07-18
  • 2012-07-04
  • 2013-03-12
  • 2016-12-08
相关资源
最近更新 更多