如何使用正则表达式匹配 Ruby 中包含特殊字符的重复模式?

Posted

技术标签:

【中文标题】如何使用正则表达式匹配 Ruby 中包含特殊字符的重复模式?【英文标题】:How to match repeating patterns containing special characters in Ruby using regex? 【发布时间】:2021-12-06 22:36:43 【问题描述】:

基本上,我正在尝试使用正则表达式来匹配 Ruby 中包含特殊字符的重复模式。如果给定模式重复但不是动态的次数,我就能够做到这一点。我要匹配的示例字符串是:

Draw a square that is coords.width pixels wide by coords.height pixels tall.

这可以通过使用轻松完成

arr = value.scan(/\\(\w+?\.\w+?)\\/).flatten

arr 运行后是这样的

["coords.width", "coords.height"]

但是我如何编写一个可以匹配的正则表达式,以防这种模式任意遵循,例如

Draw a square that is shape.rectangle.coords.width pixels wide by shape.rectangle.coords.height pixels tall.

同时在以下情况下也匹配(没有“。”)

Draw a square that is width pixels wide by height pixels tall.

【问题讨论】:

您要匹配coords.width..coords.widthcoords width 还是coords..width?您需要准确地陈述您的问题。 【参考方案1】:

可以匹配正则表达式

r = /(?<=\\)[a-z]+(?:\.[a-z]+)*(?=\\)/

Rubular demo/PCRE demo at regex 101.com

我已包含 PCRE 演示,因为 regex101.com 提供了正则表达式每个元素的详细说明(悬停光标)。

例如,

str = "Draw a square coords.width wide by coords.height " +
      "tall by coords deep deep"
str.scan(r)
  #=> ["coords.width", "coords.height"]

注意"coords deep" 不匹配,因为它没有(我假设是)有效的形式。另请注意,我不必展平来自 scan 的返回值,因为正则表达式没有捕获组。

我们可以在free-spacing模式中编写正则表达式以使其自文档化。

/
(?<=      # begin a positive lookbehind
  \\    # match 1 or more lower case letters
)         # end the positive lookbehind
[a-z]+    # match 1 or more lower case letters
(?:       # begin a non-capture group
  \.      # match a period
  [a-z]+  # match 1 or more lower case letters
)         # end the non-capture group
*         # execute the non-capture group zero or more times
(?=       # begin a positive lookahead
  \\    # match ''
)         # end positive lookahead
/x        # free-spacing regex definition mode

【讨论】:

嗨,我已经写了正则表达式/(?&lt;=\\)([a-z]+\.[a-z]*)(?=\\)/ 它工作正常。但是你已经包含了一个叫做non-capture group的东西,我不知道它是什么。你能帮我理解你为什么把它包括在内吗?还有哪些其他字符串不适用于我的正则表达式?你能帮帮我吗? @Rajagopalan,如果你想重复一系列断言,例如\.[a-z]+,你需要将它们放在捕获组或非捕获组中。 (\.[a-z]+)*(捕获组)和(?:\.[a-z]+)*(非捕获组)匹配组的内容零次或多次。如果您希望稍后提取或反向引用组的内容,则需要一个捕获组;否则,两者都可以,但首选非捕获组,因为它告诉读者您不会引用该组的内容... ....您不需要正则表达式中的捕获组,因为环视不消耗字符;只需匹配/(?&lt;=\\)[a-z]+\.[a-z]+(?=\\)/。通常你会使用环视,就像你所做的那样,或者使用捕获组:/\\([a-z]+\.[a-z]+)\\/。然而,这有问题。您的正则表达式匹配"x.",我认为这是不希望的,并且不匹配具有多个句点的示例,例如"shape.rectangle.coords.width" you need to place them in a capture group or non-capture group. (\.[a-z]+)* (capture group) and (?:\.[a-z]+)* (non-capture group) match the contents of the group zero or more times. 这一行非常清楚地解决了我的疑问。谢谢。【参考方案2】:

(/\\(.*?)\\/)

这成功了。它匹配 中的任何内容,但我总是可以在提取事件/模式时验证结构

【讨论】:

【参考方案3】:

(\+\S+)

上述模式将实现您的目标。它匹配外壳内的所有非空格字符。

【讨论】:

注意\S匹配任意字符,模式也可以匹配abc

以上是关于如何使用正则表达式匹配 Ruby 中包含特殊字符的重复模式?的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式匹配文本中包含换行符等空白字符如何匹配

正则表达式判断字符串中包含数字,大写字符,小写字母,特殊符号中的几种怎么判断?

js中如何用正则判断字符串中包含百分号

ruby 正则表达式Regexp

MySQL正则表达式匹配

python 正则表达式