如何使用regex匹配包含Ruby特殊字符的重复模式?



基本上,我正在尝试使用regex来匹配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.

同时也匹配以下情况(no ".")

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

可以匹配正则表达式

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

Rubular demo/PCRE demo at regex101.com

我已经包含了PCRE演示,因为regex101.com提供了regex的每个元素的详细解释(将光标悬停)。

例如,

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的返回值扁平化,因为regex没有捕获组。

我们可以将正则表达式写成自由空格模式以使其自描述。

/
(?<=      # 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

(/{{(.*?)}}/)

这个成功了。它匹配{{}}内的任何内容,但我总是可以在提取出现/模式

时验证结构。

({+S+)

上面的模式可以达到你的目标。它匹配所有非空格字符。