当我运行下面的脚本时,我得到了
$VAR1 = [
'ok0.ok]][[file:ok1.ok',
undef,
undef,
'ok2.ok|dgdfg]][[file:ok3.ok',
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef,
undef
];
我希望ok0.ok ok1.ok ok2.ok ok3.ok
,理想情况下ok4.ok ok5.ok ok6.ok ok7.ok
问题
谁能看到我做错了什么?
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $html = "sdfgdfg[[file:ok0.ok]][[file:ok1.ok ]] [[file:ok2.ok|dgdfg]][[file:ok3.ok |dfgdfgg]] [[media:ok4.ok]] [[media:ok5.ok ]] [[media:ok6.ok|dgdfg]] [[media:ok7.ok |dfgdfgg]]ggg";
my @seen = ($html =~ /file:(.*?) |\||\]/g);
print Dumper \@seen;
答案 0 :(得分:2)
我认为,否定的字符类可以简化一些事情。明确你的锚点(文件:或媒体:),并明确指出序列的终止(空格,管道或结束括号)。然后捕捉。
my @seen = $html =~ m{(?:file|media):([^\|\s\]]+)}g;
说明:
my @seen = $html =~ m{
(?:file|media): # Match either 'file' or 'media', don't capture, ':'
( [^\|\s\]]+ ) # Match and capture one or more, anything except |\s]
}gx;
遇到]
,|
或\s
后,捕获就会停止。
答案 1 :(得分:1)
看起来您正在尝试匹配以file:
开头并以空格,竖线或结束方括号结尾的所有内容。
正则表达式末尾的OR语句需要在(方括号)括号之间,但是:
my @seen = ($html =~ /file:(.*?)[] |]/g);
如果你想要媒体:块,或者文件部分。您可能需要一个非捕获组:
my @seen = ($html =~ /(?:file|media):(.*?)[] |]/g);
第一个语句将捕获' file:'之间的所有内容。以及]
,|
或。
第二个语句也是如此,但同时包含文件和媒体。我们使用非捕获组(?:group)
而不是(group)
,因此该字词不会放入您的@seen
。
答案 2 :(得分:1)
尝试
my @seen = ($html =~ /\[\[\w+:(\w+\.\w+)\]\]/g);
答案 3 :(得分:1)
这是你的正则表达式所做的:
...
my $ss = qr {
file: # start with file + column as anchor
( # start capture group
.*? # use any character in a non-greedy sweep
) # end capture group
\s # end non-greedy search on a **white space**
| # OR expression encountered up to here with:
\| # => | charachter
| # OR expression encountered up to here with:
\] # => ] charachter
}x;
my @seen = $html =~ /$ss/g;
...
这就是你的正则表达式应该做的事情:
...
my $rb = qr {
\w : # alphanumeric + column as front anchor
( # start capture group
[^]| ]+ # the terminating sequence
) # end capture group
}x;
my @seen = $html =~ /$rb/g;
...
如果你想要一个简洁,简洁的正则表达式并知道你做了什么,你可以完全删除捕获组,并在列表上下文中使用完整的捕获块以及正面的后视:
...
my @seen = $html =~ /(?<=(?:.file|media):)[^] |]+/g; # no cature group ()
...
或者,如果您要处理的数据中没有其他结构,请使用:
作为锚点:
...
my @seen = $html =~ /(?<=:)[^] |]+/g; # no capture group and short
...
此致
RBO
答案 4 :(得分:0)
根据文件名中可能的字符,我想你可能想要
my @seen = $html =~ /(?:file|media):([\w.]+)/g;
捕获所有ok0.ok
到ok7.ok
。
它依赖于包含字母数字字符加上下划线和点的文件名。
答案 5 :(得分:0)
我希望这是你所需要的。
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $string = "sdfgdfg[[file:ok0.ok]][[file:ok1.ok ]] [[file:ok2.ok|dgdfg]][[file:ok3.ok |dfgdfgg]] [[media:ok4.ok]] [[media:ok5.ok ]] [[media:ok6.ok|dgdfg]] [[media:ok7.ok |dfgdfgg]]ggg";
my @matches;
@matches = $string =~ m/ok\d\.ok/g;
print Dumper @matches;
输出:
$VAR1 = 'ok0.ok';
$VAR2 = 'ok1.ok';
$VAR3 = 'ok2.ok';
$VAR4 = 'ok3.ok';
$VAR5 = 'ok4.ok';
$VAR6 = 'ok5.ok';
$VAR7 = 'ok6.ok';
$VAR8 = 'ok7.ok';
此致 基兰。