如何使用正则表达式匹配 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.width
、coords 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
【讨论】:
嗨,我已经写了正则表达式/(?<=\\)([a-z]+\.[a-z]*)(?=\\)/
它工作正常。但是你已经包含了一个叫做non-capture group
的东西,我不知道它是什么。你能帮我理解你为什么把它包括在内吗?还有哪些其他字符串不适用于我的正则表达式?你能帮帮我吗?
@Rajagopalan,如果你想重复一系列断言,例如\.[a-z]+
,你需要将它们放在捕获组或非捕获组中。 (\.[a-z]+)*
(捕获组)和(?:\.[a-z]+)*
(非捕获组)匹配组的内容零次或多次。如果您希望稍后提取或反向引用组的内容,则需要一个捕获组;否则,两者都可以,但首选非捕获组,因为它告诉读者您不会引用该组的内容...
....您不需要正则表达式中的捕获组,因为环视不消耗字符;只需匹配/(?<=\\)[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 中包含特殊字符的重复模式?的主要内容,如果未能解决你的问题,请参考以下文章