[英]Perl regex match multiple instances of a pattern and replace
I have a string that looks like this: 我有一个看起来像这样的字符串:
abc[1,2,3].something.here,foo[10,6,34].somethingelse.here,def[1,2].another
I want to split this string into an array that consists of: 我想将此字符串拆分为包含以下内容的数组:
abc[1,2,3].something.here
foo[10,6,34].somethingelse.here
def[1,2].another
But splitting on the comment won't work so my next idea is to first replace the commas that reside between the square brackets with something else so I can split on the comma, then replace after the fact. 但是拆分注释不起作用,因此我的下一个想法是,先用其他东西替换方括号之间的逗号,以便我可以拆分逗号,然后在事实之后替换。
I've tried a few approaches with little success.. Any suggestions? 我尝试了几种方法,但收效甚微。
You can use look-ahead assertion in the pattern: 您可以在模式中使用先行断言:
my $s = "abc[1,2,3].something.here,foo[10,6,34].somethingelse.here,def[1,2].another";
my @a = split /,(?=\w+\[)/, $s;
When things get that complex, I like the parser approach. 当事情变得如此复杂时,我喜欢解析器方法。
#!/usr/bin/perl
use strict;
use warnings;
my $statement = "abc[1,2,3].something.here,foo[10,6,34].somethingelse.here,def[1,2].another";
my $index = qr/\[(?:\d+)(?:,\d+)*\]/;
my $variable = qr/\w+$index?/;
my $expression = qr/$variable(?:\.$variable)*/;
my @expressions = ($statement =~ /($expression)/g);
print "$_\n" for @expressions;
Iterate through the characters in the string like this (pseudocode): 像这样遍历字符串中的字符(伪代码):
found_closing_bracket = 0;
buffer = ''
array = []
foreach c in str:
if c == ']'
found_closing_bracket = 1
if c == ',' && found_closing_bracket == 1
push(array, buffer)
buffer = ''
found_closing_bracket = 0
else
buffer = buffer + c
Sure, you could use regular expressions, but personally I rather aim for a simpler solution even if it's more hackish. 当然,您可以使用正则表达式,但就个人而言,我更希望寻求一个更简单的解决方案,即使该解决方案更加笨拙。 Regular expressions are a pain to read sometimes.
正则表达式有时很难读。
An alternative to eugene y's answer: eugene y的答案的替代方法:
my $s = "abc[1,2,3].something.here,foo[10,6,34].somethingelse.here,def[1,2].another";
my @a = ($s =~ /[^,]+\[[\d,]*\]/g);
print join("\n", @a,"")
This question gave me excuse to take a look at Regexp::Grammars I wanted for some time. 这个问题让我借口看了我想要一段时间的Regexp :: Grammars 。 Following snippet works for your input:
以下代码段可用于您的输入:
use Regexp::Grammars;
use Data::Dump qw(dd);
my $input
= 'abc[1,2,3].something.here,foo[10,6,34].somethingelse.here,def[1,2].another';
my $re = qr{
<[tokens]> ** (,) # comma separated tokens
<rule: tokens> <.token>*
<rule: token> \w+ | [.] | <bracketed>
<rule: bracketed> \[ <.token> ** (,) \]
}x;
dd $/{tokens}
if $input =~ $re;
# prints
# [
# "abc[1,2,3].something.here",
# "foo[10,6,34].somethingelse.here",
# "def[1,2].another",
# ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.