匹配开始和结束"标签"没有创建第二个匹配组

时间:2014-05-16 19:19:38

标签: ruby regex

我想捕获指定标记对的内容,其内容可能包括空格和新行。这是一个例子:

{section_title}
Section 1 title 
with some white space
{/section_title}

我有一个与内容匹配的正则表达式,但会产生两个匹配的组:

\{section_title\}((.|\s)*?)\{\/section_title\}
  1. 第1节标题 有一些空白
  2. (尾随空格)
  3. 变体与内容匹配而不创建第二个匹配组,但不允许包含嵌套标记,我希望能够允许。

    \{section_title\}([^\{]*?)\{\/section_title\}
    

    有没有办法重构第一个正则表达式以避免第二个匹配组?我知道我可能只删除所有"白色空间"匹配,但想知道是否只有正则表达式。

    另外,如果可能的话,我想匹配标签的替代版本:

    {st}
    Section 1 title 
    with some white space
    {/st}
    

    可以在捕获组中添加备选方案

    \{(section_title|st)\}((.|\s)*?)\{\/(section_title|st)\}
    

    但我想再次避免额外的比赛。这可能吗?

    我使用的是Ruby 1.9.3。

1 个答案:

答案 0 :(得分:0)

我认为最简单的方法是将((.|\s)*?)更改为(.*?)并将(?m)添加到正则表达式的开头,这会导致.也匹配行符。

str = "{sec_title}\nSection 1 title \nwith some white space\n{/sec_title}\n"

r = /(?m)\{sec_title\}(.*?)\{\/sec_title\}/
str[r,1]      #=> "\nSection 1 title \nwith some white space\n"
1中的

str[r,1]是对(.*)捕获的内容的引用。

概括,

str = "{s1}\nSection 1 title \nwith some white space\n{/s1}\n"

r = /(?m)\{(\w+)\}(.*?)\{\/\1\}/
str[r,2]      #=> "\nSection 1 title \nwith some white space\n"

现在\1是对第一个捕获组(\w+)捕获的内容的反向引用,而2是对第二个捕获组捕获的内容的引用,{{ 1}}。

对于多对,

(.*)

我们可以将它包装在一个带有可变数量参数

的方法中
str = "{s1}{s2}\nSection 1 title \nwith some white space\n{/s2}{/s1}\n"

str[r,2]      #=> "{s2}\nSection 1 title \nwith some white space\n{/s2}"
str[r,2][r,2] #=> "\nSection 1 title \nwith some white space\n"

我们称之为

def parse(str, *names)
...
end