【问题标题】:Regex consume a character if it matches, but not otherwise正则表达式如果匹配则消耗一个字符,否则不消耗
【发布时间】:2018-03-02 11:58:55
【问题描述】:

我正在尝试编写一个正则表达式,它将捕获“@”字符的所有实例,except 当两个这样的字符连续出现时(本质上是一个转义序列)。例如:

abd@ajk: @ 应该匹配

abd@@ajk: 没有匹配项

abd@@@ajkfinal @ 应该匹配。

abd@@@@ajk: 没有匹配项

这几乎适用于负前瞻表达式@(?!@),除了因为第二个@ 未被消耗,两个@ 符号中的最后一个仍将匹配。我想我想要做的是向前看一个@,但如果它存在的话就消耗它;否则,请勿食用。这可能吗?

编辑:我正在使用 Javascript,不幸的是,它排除了几种好的方法:(

【问题讨论】:

标签: javascript regex regex-lookarounds


【解决方案1】:

在 JavaScript 中,要在未转义的 @ 处拆分字符串,您实际上可以匹配 块文本,即 @@(转义的 @)和除 @987654325 之外的任何字符@:

var strs = ['abd@ajk','abd@@ajk','abd@@@ajk','abd@@@@ajk'];
var rx = /(?:[^@]|@@)+/g;
for (var s of strs) {
	console.log(s, "=>", s.match(rx))
}

正则表达式是

/(?:[^@]|@@)+/g

its demo

详情

  • (?: - 非捕获组的开始,匹配两个备选方案中的任一个:
    • [^@]- any char other than@`
    • | - 或
    • @@ - 2 @s
  • )+ - 重复匹配 1 次或多次。

g 修饰符查找输入字符串中的所有匹配项。

【讨论】:

    【解决方案2】:

    由于您没有为您的问题标记编程语言,这里是我为 Java 支付的 2 美分:

    (?<=(?<!@)(?:@@){0,999})@(?!@)
    

    Java 不支持无限后视,但有界,所以在这里我明确指定了 @:999 偶数出现的最大值。

    JavsScript

    许多浏览器尚未实现和支持 JavaScript 中的 Lookbehinds。如果您尝试在 JS 中执行此操作,那么这将是您的工作解决方案:

    方法一

    ((?:[^@]*(?:@@)+[^@]*)+)|@
    
    • (?:[^@]*(?:@@)+[^@]*)+ 匹配 @@ 出现次数及其所有前导/尾随字符
    • |@ 或单个@

    JS代码:

    str.split(/((?:[^@]*(?:@@)+[^@]*)+)|@/).filter(Boolean);
    

    方法二(推荐)

    或者,如果您对使用 match() 没有问题,这会更干净,当然也更快:

    (?:[^@]*(?:@@)+[^@]*)+|[^@]+
    

    JS代码:

    console.log(
      "aaaa@@@@@@@bbb@aa@@@cccc@@ddddd@".match(/(?:[^@]*(?:@@)+[^@]*)+|[^@]+/g)
    );

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-20
      • 1970-01-01
      • 2016-05-12
      • 1970-01-01
      • 2023-03-13
      • 2019-08-17
      相关资源
      最近更新 更多