当前位置: 首页 > 知识库问答 >
问题:

匹配perl正则表达式中括号和方括号外的所有逗号

丌官招
2023-03-14

我试图匹配,使用正则表达式,所有逗号(后跟一个空格):在任何括号或方括号之外,即逗号不应该包含在括号或方括号中。

目标字符串是A,An(hi,world[hello,(hi,world)world]);这个,这些。在这种情况下,它应该匹配第一个逗号和最后一个逗号(介于AAn之间,这个这些)。

所以我可以拆分A,An(hi,world[你好,(hi,world)world]);this,这些分成AAn(hi,world[你好,(hi,world)world]);thisand这些,不会因此而使括号/括号不平衡。

为此,似乎很难单独使用正则表达式。有没有其他办法解决这个问题?

我使用的正则表达式:, (?![ ^()\[\]]*[\)\]])

但是这个表达式将匹配另外两个不应该匹配的逗号(第二个和第三个)。

虽然如果它与以下字符串匹配,它将匹配正确的逗号(分别是第一个):A,An(hi,world)A,An[hi,world]

但是,如果括号和方括号相互包含,就会出现问题。

更多详细信息请访问此链接:https://regex101.com/r/g8DOh6/1

共有3个答案

巫马炫明
2023-03-14

ZDIM提到的一种方法是使用核心文本::Ba剪裁模块。演示:

#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
use Text::Balanced qw/extract_bracketed/;

my $str = "A, An(hi, world[hello, (hi , world) world]); This, These";
my ($inside, $after, $before) = extract_bracketed $str, '()[]', qr/[^([]*/;

my @tokens = (split(/,/, $before//""), $inside, split(/,/, $after//""));

# Displays
# A  An (hi, world[hello, (hi , world) world]) ; This  These
say join(' ', @tokens);
孟承嗣
2023-03-14

检查逗号是否在括号/括号内,例如。

[(,),],[abc,(def,[ghi,],),],[(,),]
      ^                    ^

这意味着模式必须知道这些括号/括号中的每一个是何时以平衡的方式打开和关闭的,所以不仅仅是例如[([]),因为它应该是[([])]

这里有一个替代解决方案,不能直接解决你的问题,但可能更近一步。

>

a、 逗号

b.包在外部[]()中的组参见正则表达式以匹配平衡括号

过滤掉1。b

(?:\((?>[^()]|(?R))*\)|\[(?>[^\[\]]|(?R))*\]|,)

对于该字符串,匹配项如下所示:

A, An(hi, world[hello, (hi , world) world]) and this, is that, for [the, one (in, here, [is not,])] and last,here!
 ^   ^------------------------------------^         ^        ^     ^------------------------------^         ^
  • 因此,它没有捕获任何括号/括号组中的任何逗号,因为它捕获了它们作为一个整体。现在,在外层有逗号
翟嘉祥
2023-03-14

这里的问题是识别“平衡”对,在这种情况下是括号/括号。这是一个公认的问题,对此有库。他们可以找到顶层匹配对,(...)/[...],里面有所有内容,括号之外还有所有其他内容——然后处理“其他”

一种方法是使用Regexp::Common

use warnings;
use strict;
use feature 'say';

use Regexp::Common;

my $str = shift // q{A, t(a,b(c,))u B, C, p(d,)q D,}; 

my @all_parts = split /$RE{balanced}{-parens=>'()[]'}/, $str;

my @no_paren_parts = grep { not /\(.*\) | \[.*\]/x } @all_parts;

say for @no_paren_parts;

当分隔符模式中的正则表达式捕获时,它使用split的属性返回包含分隔符的列表库regex捕获了所有内容,因此我们将其全部取回——通过将字符串拆分为regex匹配的内容以及regex匹配的部分而获得的部分。分隔符包含成对的分隔符,而其他术语则不能,通过构造,因此我将它们过滤掉——打印

A, t
u B, C, p
q D,

paren/括号术语没有了,但是如何分割字符串有点武断。

上面的有点“通用”,使用库仅仅提取平衡对()/[],以及字符串的所有其他部分。或者,我们可以从字符串中删除这些模式

$str =~ s/$RE{balanced}{-parens=>'()[]'}//g;

待在一起

A, tu B, C, pq D,

现在可以简单地用逗号分割

my @terms = split /\s*,\s*/, $str;
say for @terms;

对于

A
tu B
C
pq D

正如评论中所阐明的,这是本案的预期结果。

另一个最著名的库,在许多方面更基本,是核心Text::Balance。看看肖恩在这里的回答,比如这篇文章,这篇文章和这篇文章。

举个例子。具有

my $str = q(it, is; surely);

my @terms = split /[,;]/, $str;

当使用

my @terms = split /([,;])/, $str;

我们进入@术语所有: 当然

——同样通过构造,它包含正则表达式在偶数索引中匹配的内容。因此,对于所有其他部分,我们可以获取奇数索引的元素

my @other_than_matched_parts = @all_parts[ grep { not $_ & 1 } 0..$#all_parts ];

 类似资料:
  • 问题内容: 匹配字符串中的’(’的正则表达式是什么? 以下是场景: 我有一串 我想使用正则表达式拆分字符串。为此,我正在使用 但是我收到以下异常。 转义似乎不起作用。 问题答案: 两种选择: 首先,你可以使用转义 回 斜线- 另外,由于它是单个字符,因此您可以将其放入不需要转义的字符类中-

  • 问题内容: 我有一个类似于以下内容的字符串: 我想创建一个与逗号匹配的正则表达式,但只匹配不在括号内的逗号(在上面的示例中,除23和45之后的两个逗号之外,所有其他逗号)。我将如何做(如果使用Java正则表达式会有所不同)? 问题答案: 假定没有嵌套的括号(否则,你不能使用Java Regex来完成此任务,因为不支持递归匹配): 此正则表达式使用否定的超前断言来确保下一个括号(如果有)不是闭合括号

  • 我需要替换括号和引号外的所有逗号 仅考虑括号替换,我有以下正则表达式 我做了下面的正则表达式,在一个组中选择括号和引号内的内容,在另一个组中选择括号外的逗号,但我没有找到一种简单的方法来只替换一个组的字符串

  • 本文向大家介绍正则表达式匹配括号外的符号及数据,包括了正则表达式匹配括号外的符号及数据的使用技巧和注意事项,需要的朋友参考一下 正则表达式匹配括号外的符号 [\\?!/\\.,\\s]+(?=[^\\)]*(\\(|$)) 将括号外的?!/.,和空格(连续多个时同时)匹配 如 结果: sdfsdf sdlfksd sdf fsdf&sdf(s:1,g:1) sdfsd sdf sdfl asdf

  • 问题内容: 我有类似的东西 商店 结束行像1商店..我想匹配,它使用python正则表达式。 我尝试了类似的方法, 但是没有用。 编辑:添加代码,我试过 请帮助。 谢谢吉乔 问题答案: 或多或少直接回复您的评论 尝试这个 解决方案是使用,而不是使用后者,因为后者试图将整个字符串与regexp匹配,而前者只是试图在字符串内部查找与表达式匹配的子字符串。

  • 上面的正则表达式返回括号之间的文本。 如: 如何重写上面的正则表达式,所以我提供了一个类似的字符串,它将返回。i、 e带括号的部分,其中包含大括号中的字符串。