【问题标题】:Java regex : How to reuse a consumed character in pattern matching?Java regex:如何在模式匹配中重用消耗的字符?
【发布时间】:2013-03-31 08:55:00
【问题描述】:

有没有办法在模式匹配中重用源的消耗字符?

例如,假设我想找到一个带有正则表达式(a+b+|b+a+)的模式 即多个 a 后跟多个 b 或反之亦然。

假设输入是aaaabbbaaaaab

那么使用正则表达式的输出将是aaaabbbaaaaab

我怎样才能得到输出是

aaaabbb
bbbaaaaa
aaaaab

【问题讨论】:

标签: java regex


【解决方案1】:

试试这个方法

String data = "aaaabbbaaaaab";
Matcher m = Pattern.compile("(?=(a+b+|b+a+))(^|(?<=a)b|(?<=b)a)").matcher(data);
while(m.find())
    System.out.println(m.group(1));

这个正则表达式使用look around 机制并且会发现(a+b+|b+a+)

  • 存在于输入的开头^
  • b 开头,由a 预测
  • a 开头,由b 预测。

输出:

aaaabbb
bbbaaaaa
aaaaab

这个正则表达式中是否需要^

是的,如果没有^,这个正则表达式不会捕获放在输入开头的aaaabbb

如果我不在(?=(a+b+|b+a+)) 之后添加(^|(?&lt;=a)b|(?&lt;=b)a),则此正则表达式将匹配

aaaabbb
aaabbb
aabbb
abbb
bbbaaaaa
bbaaaaa
baaaaa
aaaaab
aaaab
aaab
aab
ab

所以我需要将此结果限制为仅以 a 开头且前面有 b 的结果(但不包括匹配中的 b - 所以向后看非常适合)和 b 即由a 预测。

但我们不要忘记ab,它们位于字符串的开头,并且不会被任何东西预测。要包含它们,我们可以使用^


也许用这个正则表达式来表达这个想法会更容易

(?=(a+b+|b+a+))((?&lt;=^|a)b|(?&lt;=^|b)a).

  • (?&lt;=^|a)b 将匹配位于字符串开头的b,或者前面有a
  • (?&lt;=^|b)a 将匹配位于字符串开头的a,或者前面有b

【讨论】:

  • 非常感谢:)。这是一个非常明确的答案。我看过 regex buddy,但仍然有些困惑,因为我对 regex 真的很陌生。在正则表达式中,您能否进一步解释一下 ^ 的含义?再次感谢您的出色回答:)。
  • @dgun ^ 是匹配字符串开头的anchor
  • 这个正则表达式中是否需要 ^?这是为什么? (对不起,如果那很愚蠢,我只是好奇:))
  • @dgun 检查我编辑的答案。如果还有不明白的地方就问吧。
  • 这很有帮助:)。谢谢!
【解决方案2】:

你可以用lookbehind来模拟这个:

((?<=a)b+|(?<=b)a+)

这个输出

bbb aaaaa b

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-07
    • 1970-01-01
    相关资源
    最近更新 更多