【问题标题】:Match opening and closing "tags" without creating a second match group在不创建第二个匹配组的情况下匹配开始和结束“标签”
【发布时间】:2014-05-16 19:19:38
【问题描述】:

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

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

我有一个匹配内容的正则表达式,但结果是两个匹配组:

\{section_title\}((.|\s)*?)\{\/section_title\}
  1. 第 1 节标题 有一些空白
  2. (尾随空格)

变体匹配内容而不创建第二个匹配组,但不允许包含嵌套标签,我希望能够允许。

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

有没有办法重构第一个正则表达式以避免第二个匹配组?我知道我可能可以删除所有“仅空白”匹配项,但想知道是否存在仅正则表达式的方法。

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

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

可以在捕获组中添加替代项

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

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

我使用的是 Ruby 1.9.3。

【问题讨论】:

    标签: ruby regex


    【解决方案1】:

    我认为最简单的方法是将((.|\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"
    

    str[r,1] 中的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 是对第二个捕获组(.*) 捕获的内容的引用。

    对于多对,

    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
    

    我们称之为

    parse(str, "s1, "s2")
    

    【讨论】:

    • (.|\s)* 切换到/m 模式.* 很好,但我不会急于放弃非贪婪修饰符。 (?m){name}(.*}{/name} 将从第一个 {name} 匹配到最后一个 {/name},因此如果有多个同名部分,则会匹配太多。如果只有一个{name} 部分,但文档非常大,(.*?) 往往会比(.*) 快得多。
    • 谢谢。 @艾伦。我会相信你并把它放回去。事实上,我对 HTML 只是模糊地熟悉!我做了一个似乎不正确的假设,即所有名称都是唯一的。
    • 谢谢,这真的很优雅。另外,感谢您逐步解释该过程!
    猜你喜欢
    • 2016-09-15
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 2012-04-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多