首先:如果您想正确解析某些编程语言或配置格式,您可能需要使用actual parser。
但是,您可以使用正则表达式来完成您的任务。但是我们不会编写正则表达式来匹配我们想要拆分的逗号。相反,我们编写了一个匹配列表部分的正则表达式:
my $regex = qr/
\w+ # item can begin with some identifier
\{ [^\}]* \} # followed by some stuff in braces
[,;] # must end with comma or semicolon
/x;
然后我们可以像这样提取匹配项
my $string = "foo{a},bar{b}, baz{c,d,e};";
my @result = $string =~ /$regex/g;
dd @result; # using dd from Data::Dump
输出:
("foo{a},", "bar{b},", "baz{c,d,e};")
相当不错。现在,我们通过两种方式改进我们的正则表达式:
- 逗号不是匹配字符串的一部分
- 我们确保匹配是相邻的,并且中间没有垃圾
- 我们以最简单的方式使分隔符可插入:我们将一些值插入到 charclass 中。
一起:
my $delims = quotemeta "{}";
my $regex = qr/
\w+
[$delims] [^$delims]* [$delims]
/x;
my $string = "foo{a},bar{b}, baz{c,d,e};";
my @result = $string =~ /\G ($regex) [,;] \s*/xg;
dd @result;
\G 断言锚定上一个匹配停止的位置。
输出:
("foo{a}", "bar{b}", "baz{c,d,e}")
太棒了。这可以通过两种方式进一步细化:
- 大括号里的东西是允许递归的
- 我们区分打开和关闭分隔符,并且只允许正确的对。事实上,
foo}a{ 将是一个有效的项目......。
如果不需要所有这些,当前的正则表达式应该就可以了。