Regex 用正则表达式过滤匹配模式

Regex 用正则表达式过滤匹配模式,regex,perl,filter,Regex,Perl,Filter,我不太熟悉perl中的正则表达式。 我想从字符串中筛选名称,例如“儿童米克·贾格尔儿童约翰·韦恩·儿童阿基米德”标签之间的“儿童” 结果应该是: mick jagger john wayne archimedes 字符串中的名称数是可变的 我的perl程序: #!/usr/bin/perl use strict 'vars'; use strict 'subs'; my ($x); my $s="child mick jagger child john wayne child archi

我不太熟悉perl中的正则表达式。
我想从字符串中筛选名称,例如“
儿童米克·贾格尔儿童约翰·韦恩·儿童阿基米德
”标签之间的“
儿童

结果应该是:

mick jagger

john wayne

archimedes
字符串中的名称数是可变的

我的perl程序:

#!/usr/bin/perl

use strict 'vars';
use strict 'subs';
my ($x);
my $s="child mick jagger child john wayne child archimedes";

my @f=$s=~/(child.+(?!child))/igs;
foreach $x (@f)
{
    print "$x\n";
}; 
这个程序不起作用。有人能帮忙吗?

您可以使用:

\bchild \K(?:(?!child).)*(?!\S)
  • \b子项
    匹配前面有单词边界,后面有空格的子项
  • \K
    忘记匹配的内容
  • (?:(?!child)。*
    匹配任何字符,但不后跟child的换行符除外
  • (?!\S)
    断言右侧的字符不是非空白字符

或者使用非贪婪点变体

\bchild \K.+?(?= child|$)

您也可以使用lookback执行此操作:


尝试使用
split
grep
。虽然这种方法比其他一些解决方案要长,但它使程序员的意图更加明确:

perl -le '
$str = q{child mick jagger child john wayne child archimedes};
@names = grep { m{ \S }x } split m{\s* \b child \b \s* }x, $str;
print "@names";
' 
split
在您想要去除的模式上打断字符串
$str
m{\s*\b child\b\s*}x
-
child
,由分词
\b
包围,前导和尾随空白字符为0或更多
\s

需要使用
\b
来防止作为名称一部分的
child
拆分,例如Rothschild
split
返回一个包含所需输出的数组,但也包含一个额外的前导元素(空字符串),该元素是由
$str
中前导
左侧的空字符串产生的
grep
对于非空白字符(
m{\S}x
)删除此额外元素,只留下所需的输出:名称。
注意
x
regex修饰符的使用,它“通过允许空白和注释来扩展模式的易读性”

另请参见:
正则表达式上的Perl文档:perlre:.

-如果通过单击有助于解决问题,请随意将其视为已接受✓ 在这个答案的左边。请注意,接受一个解决方案会得到2。
use strict;

my $s="child mick jagger child john wayne child archimedes";
my @f = $s =~/(?<=\bchild )(?:(?! child).)+/ig;
foreach my $x (@f) {
    print "$x\n";
};
mick jagger
john wayne
archimedes
perl -le '
$str = q{child mick jagger child john wayne child archimedes};
@names = grep { m{ \S }x } split m{\s* \b child \b \s* }x, $str;
print "@names";
'