匹配*连续*行,以任意数量的空格开头,后跟一个字符

时间:2014-03-06 22:06:24

标签: regex recursive-regex

我正在尝试匹配连续行,该行以任意数量的空格开头,后跟字符|。我使用s标记,以便.匹配换行符。

到目前为止,我在|之前使用了有限数量的空格。

我遇到的问题是确定到达的线路不符合要求。出于某种原因\n\s*[^\|]没有做到这一点。我现在正在做的是以下内容:

(?P<terminating>
    \n(             # when newline is encountered...
        [^\|\s]         #   check if next character is not: (| or space)
        |
        [\s][^\|\s]     #   check if next characters are not: space + (| or space)
        |
        [\s][\s][^\|\s] #   check if next characters are not: space + space + (| or space)... And so on....
    )
    |
    $
)

这显然只适用于两个空格。我想为任意数量的空间做这项工作。我调查了递归,但在这种情况下,这似乎是非常重的枪。现在这是我的问题:为什么\n\s*[^\|]不起作用,还有另一种解决方法而不递归吗?


以下是我想要获得的输入和结果匹配的示例:

输入字符串:

Lorem ipsum dolor sit amet, 
consectetur adipisicing 
elit, 
|sed do 
        |eiusmod tempor incididunt 
     |ut labore et dolore magna aliqua.
Ut enim ad minim veniam, 
quis nostrud exercitation 
ullamco laboris nisi ut 
aliquip ex ea commodo consequat.

输出是一个包含内容的字符串:

|sed do\n        |eiusmod tempor incididunt\n     |ut labore et dolore magna aliqua.

想要与其中包含|的每一行进行三场比赛。

4 个答案:

答案 0 :(得分:2)

如果您正在使用PHP,那么应该这样做:

(?m)^\h*\|.*(?:\R\h*\|.*)*

有些兴趣点:

  • \h匹配水平空格,即空格和制表符

  • \R匹配行分隔符,无论是\n\r\n还是\r

  • (?m)启用多行模式,允许^匹配行的开头

  • 单线/ DOTALL模式设置,因为我们希望.*停在该行的末尾。

  • 我从不使用\s因为它匹配任何空白字符,包括空格,制表符,回车符(\r)和换行符(\n )。如果您只想查找可能跨越多行的匹配项,则可以在单行模式下使用\s.。但是这个任务涉及根据相对于行开头的位置来匹配事物。如果你明确地匹配不同种类的空白字符,那就容易多了。

如果您使用的是Python \h\R缩写不起作用,那么您必须更加详细:

(?m)^[ \t]*\|.*(?:[\r\n]+[ \t]*\|.*)*

请注意,[\r\n]+也会匹配空行;如果你想确保行之间只有一个行分隔符,请改用:

(?m)^[ \t]*\|.*(?:(?:\r\n|[\r\n])[ \t]*\|.*)*

答案 1 :(得分:1)

您可以在没有s修饰符的情况下尝试此模式:

(?:(?:^|(?<=\n))[^\S\r\n]*\|.*(?:\r?\n|$)?)+

答案 2 :(得分:0)

我自己解决了。我想我必须从我排除的字符组中排除空格:

n\s*[^\|\s]

不太确定为什么会这样,我偶然发现了这件事。如果有人能够解释这背后的原因,我将不胜感激。

现在的完整表达如下:

'/
    (?:
        (^|\n)\s*\|
    )
    (?P<main>
        .*?
    )
    (?=
        \n\s*[^\|\s]
        |
        $
    )
/sx'

答案 3 :(得分:0)

对于使用perl的用户,可以使用以下代码。我相信它会更好。我很乐意了解是否有人可以帮助我增强代码

my $Str = "Lorem ipsum dolor sit amet,
consectetur adipisicing
elit,
|sed do
        |eiusmod tempor incididunt
     |ut labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation
ullamco laboris nisi ut
aliquip ex ea commodo consequat.";
@lLine = split('\n', $Str);
foreach $lLine (@lLine) {
    if($lLine =~ /^[\s\|]+.*$/) {
        $ReturnStr .= $lLine;
    }
}

输出结果为: | sed do | eiusmod tempor incididunt | ut labore et dolore magna aliqua。