要在不在匹配大括号内的空间上拆分的Regexp

要在不在匹配大括号内的空间上拆分的Regexp,regex,perl,Regex,Perl,在PerlV5.30中,我需要在空格上拆分字符串,空格不在匹配的大括号内。例如: "A {B C} D" -> A|{B C}|D "A{B C}D" -> A{B C}D "A{ B }C" -> A{ B }C "AB {C D} EF" -> AB|{C D}|EF 有什么想法吗?我猜也许这个表达 my @arr = $str =~ /(?:\S+)?{[^}]*}(?:\S+)?|\S+/g; 也许可以调查一下 如果您希望探索/简化/修改该

在PerlV5.30中,我需要在空格上拆分字符串,空格不在匹配的大括号内。例如:

"A {B C} D"   -> A|{B C}|D
"A{B C}D"     -> A{B C}D
"A{ B }C"     -> A{ B }C
"AB {C D} EF" -> AB|{C D}|EF

有什么想法吗?

我猜也许这个表达

my @arr = $str =~ /(?:\S+)?{[^}]*}(?:\S+)?|\S+/g;
也许可以调查一下

如果您希望探索/简化/修改该表达式,它已被删除 在的右上面板上进行了说明 . 如果你愿意,你可以 也可以观看,它将如何匹配 对照一些样本输入

只要{和}是平衡的,并且没有转义,您就可以使用此正则表达式在不在{…}内的水平空白上进行拆分:

正则表达式详细信息:

\h+:匹配1个或多个水平空白 ?![^{]*}:当当前位置和}之间有0个或多个非{字符时,用于断言失败的先行条件
基于正则表达式的解决方案必然需要使用递归来处理嵌套大括号

my @a;
push @a, $1
   while
      $str =~ /
         \G
         \s*+
         (  (?: [^\s{}]++
            |   \{ (?&CURLY_BODY) \}
            )++
         )

         (?(DEFINE)
            (?<CURLY_BODY>
               (?: [^{}]++
               |   \{ (?&CURLY_BODY) \}
               )*+
            )
         )
      /xg;

请注意,上述操作不执行任何验证,这意味着它不会在不匹配的大括号上产生任何错误。

谢谢-我又添加了两个示例,因为它比我想象的要难一点-我怀疑它可能需要一些递归。只是再次更新-使用另一个测试,这会导致问题…在嵌套大括号上不起作用,OP所说的可能发生。是否存在类似AB{C{X Y}D}EF的字符串?从技术上讲,是的,但我只关心顶级大括号。有用提示:您可以通过或在自己的数据上测试自己的正则表达式。如果你做了一个帐户,你也可以保存你的测试用例。很好,这是非常聪明的。我尝试了这么多像这样的变化,只要{和}是平衡的,不受重视的,并且没有逃避,这就行了。这对于AB{C{X Y}D}EF是失败的,OP说可能会发生这种情况。你可能是对的,但看看问题,所示的例子中没有一个有嵌套的括号。如果通过给出明确的例子来提问,我的答案会完全不同。是的,OP本可以更清楚,但你没有提到你所做的主要假设。不过,提到另外两个很值得称赞。所有这些都不能改变这个答案不起作用的事实。需要平衡良好的大括号。它不应该,它也应该匹配垃圾,-1。你应该只需要一个捕获组就可以做到这一点,@sln,如果它也应该匹配垃圾,我不知道你的意思。我的意思是,我提供的代码确实接受垃圾代码。当然,当你这样做时,它会返回垃圾。就像你的解决方案一样。就像你的解决方案一样。你的解决方案一点也不像我的解决方案。您的有standalone\G,当它不匹配时,它将完全放弃。你的不匹配未配对的括号你的垃圾使用2个捕获组。忽略空白是匹配的一部分这一事实,并且您的正则表达式使用2个捕获组-您的正则表达式不适用于AB{C{X Y}D}EF{as{D}f捕获组1给出了AB{C{X Y}D}EF而不是所需的AB{C{X Y}D}EF as{D}f、 你把重点放在平衡大括号上,但如果不是的话就不处理它们。你不关心默认值,而且在所有情况下,你的正则表达式都会退出。我从来没有说过它会提供与你的解决方案相同的输出。
my @a;
push @a, $1
   while
      $str =~ /
         \G
         \s*+
         (  (?: [^\s{}]++
            |   \{ (?&CURLY_BODY) \}
            )++
         )

         (?(DEFINE)
            (?<CURLY_BODY>
               (?: [^{}]++
               |   \{ (?&CURLY_BODY) \}
               )*+
            )
         )
      /xg;