【问题标题】:Scala Regex Positive and Negative Look Behind at the same timeScala Regex 正面和负面同时回顾
【发布时间】:2019-10-16 20:13:41
【问题描述】:

我有一个这样的输入字符串

val input = """["abc:def&ghi:jkl"]"""

我想提取 abcghi 所以我写了这个有效的正则表达式

val regex = """(?<=["&])(\w+)(?=[:])""".r
regex.findAllIn(input).foreach(println)

所以基本上我对: 进行了展望,对"&amp; 进行了展望。

到目前为止一切顺利。但现在我有这样的输入

val input = """["abc:de_&_f:xyz&ghi:jkl"]"""

匹配

abc
_f
ghi

我想改变我的正则表达式的逻辑说。

: 的前瞻为真,&amp; 的后视为真,_&amp;_ 为假时,匹配\w+

所以我想同时使用正面和负面的外观。我该怎么做?

【问题讨论】:

  • 第二次输入的预期结果是什么?
  • 非正则表达式解决方案怎么样? 1) 第一个字符串:substring(0, index_of_first_colon)。 2) 第二个字符串:substring(index_of_ampersand, index_of_next_colon)。对结果应用过滤器也应该很容易。
  • 预期输出与第一个输出相同
  • 问题是关于正则表达式的。
  • @KnowsNotMuch 确定。这就是我发表评论的原因。似乎在: 上进行一些简单的过滤可以很容易地产生相同的结果。

标签: regex scala


【解决方案1】:

您可以在正则表达式的后向表达式中添加一个否定的lookbehind和一个否定的lookahead,如下所示:

(?<=(?:(?<!_)&(?!_)|"))\w+(?=:)

RegEx Demo

在这里,我们在后视条件中使用了一个交替,即:

  • (?&lt;!_)&amp;(?!_)|":匹配&amp;,如果其前后没有_
  • |:或者
  • " 匹配 "

对于您的情况,这个较短的正则表达式也可能有效:

(?<=["&])(?<!_&)\w+(?=:)

RegEx Demo 2

如果\w+ 前面有_&amp;(?&lt;!_&amp;) 将跳过匹配项。

【讨论】:

  • 非常好的解决方案! +1
【解决方案2】:

您可以首先使用否定字符类[^\W_]\w* 更新您的模式以不匹配\w 中的下划线

由于您只想要一个匹配,您可以省略捕获组(),并且可以省略[:] 中的方括号。

(?<=["&])[^\W_]\w*(?=:)
  • (?&lt;=["&amp;]) 正面向后看,断言左边是"&amp;
  • [^\W_] 匹配除_ 之外的单词字符
  • \w* 匹配 0+ 个单词字符
  • (?=:) 正向前瞻,断言右边是:

Regex demo | Scala demo

【讨论】:

  • 但这不适用于输入val input = "a_bc:def"。我们只有在遇到_&amp;_ 时才需要跳过。
  • @KnowsNotMuch 你是这个意思吗? regex101.com/r/KqDNX6/1
  • 这行得通。我的问题是我们可以在积极和消极的后视之间做一个 AND 吗?
猜你喜欢
  • 2013-08-03
  • 2016-09-07
  • 1970-01-01
  • 2022-11-10
  • 2016-05-19
  • 1970-01-01
  • 2023-02-22
  • 2015-12-10
  • 1970-01-01
相关资源
最近更新 更多