0

我正在尝试匹配以任意数量的空格开头的连续行|,然后是字符。我正在使用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

4 回答 4

2

如果您使用的是 PHP,应该这样做:

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

一些兴趣点:

  • \h匹配水平空格,意思是空格和制表符

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

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

  • singleline/DOTALL 模式设置,因为我们希望.*在行尾停止。

  • 我从不使用\s,因为它匹配任何空白字符,包括空格、制表符、回车符 ( \r) 和换行符 ( \n)。如果您只想找到可能跨越多行的匹配项,可以使用\sor.单行模式。但是这个任务涉及根据它们相对于行首的位置来匹配事物。如果您明确匹配不同类型的空白字符,这会容易得多。

如果您使用的是 Python\h\R简写将不起作用,因此您必须更加详细:

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

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

(?m)^[ \t]*\|.*(?:(?:\r\n|[\r\n])[ \t]*\|.*)*
于 2014-03-07T00:09:00.453 回答
1

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

(?:(?:^|(?<=\n))[^\S\r\n]*\|.*(?:\r?\n|$)?)+
于 2014-03-06T22:09:52.463 回答
0

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

n\s*[^\|\s]

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

现在的完整表达式如下:

'/
    (?:
        (^|\n)\s*\|
    )
    (?P<main>
        .*?
    )
    (?=
        \n\s*[^\|\s]
        |
        $
    )
/sx'
于 2014-03-06T23:20:33.680 回答
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 laboure et dolore magna aliqua。

于 2014-03-26T10:53:11.660 回答