【问题标题】:Regex cuts word if end of string如果字符串结束,正则表达式会剪切单词
【发布时间】:2016-09-09 19:39:57
【问题描述】:

我想在多行文本中检查和捕获目标字符串前后的 2 个或 x 个单词。问题是如果匹配的单词少于x个单词,那么正则表达式会切断最后一个单词并将其拆分到x。

例如

text = "This is an example /year"

如果示例是目标:

匹配数据:“is”、“an”、“/yea”、“r”

如果我在 /year 之后添加随机单词,它会正确匹配。

我该如何解决这个问题,以便如果存在少于 x 个单词就停在那里或为其余匹配返回空?

应该是这样的

匹配数据:“is”、“an”、“/year”、“”

def checkWords(target, text, numLeft = 2, numRight = 2)

target = target.compact.map{|x| x.inspect}.join('').gsub(/"/, '')

    regex = ""
    regex += "\\s+{,2}(\\S+)\\s+{,2}" * numLeft
    regex += target
    regex += "\\s+{,2}(\\S+)" * numRight

    pattern = Regexp.new(regex)
    matches = pattern.match(text)

    puts matches.inspect

end

【问题讨论】:

  • regex += "\\s+{,2}(\\S+)\\s+{,2}" * numLeft 更改为regex += "(?:\\S+\\s+){0," + numLeft + "}""\\s+{,2}(\\S+)" * numRight 更改为"(?:\\s+\\S+){0," + numRight + "}"。见ideone.com/7l7rBW
  • @WiktorStribiżew 是的,将其更改为 "(?:(\\S+)\\s+){0,#{numLeft}}" 但它不捕获 2 个单词。前后只有1个。即使我增加 numLeft 和 numRight。实际上它甚至不匹配正确的单词
  • here,它与Bridge Station target a year 匹配得很好。我还要记住,您的搜索词可以包含任何非空白符号。
  • 这是重复捕获组的预期行为,一旦在量化组中,最后一次迭代中捕获的值仅存储在组缓冲区中。使用它like this

标签: ruby regex


【解决方案1】:

由于您要捕获 target 之前和之后的单词,因此您需要围绕匹配 0 到 2 次出现的空格的整个正则表达式部分设置一个捕获组- 非空格。此外,您需要允许0 的最小界限 - 使用{0,2}(或更简洁的{,2})限制量词,以确保即使右侧缺少上下文,您也可以获得左侧的上下文:

/((?:\S+\s+){,2})target((?:\s+\S+){,2})/
 ^              ^      ^              ^

this Rubular demo

如果您使用/(?:(\S+)\s+){0,2}target(?:\s+(\S+)){0,2}/,所有捕获的值(最后一个除外)都将丢失,即一旦量化,重复捕获组仅将上次迭代期间捕获的值存储在组缓冲区中。

另请注意,在+ 量词上设置{,2} 量词是没有意义的,\\s+{,2} = \\s+

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    • 2016-12-20
    • 2013-07-24
    • 2011-12-13
    相关资源
    最近更新 更多