我有一个文件,其中包含一些完全大写的单词和一些混合大小写的单词,我想提取完全大写的单词(包含在一行中) - 即由\b
分隔并包含的内容至少两个大写字母,没有小写字母。一切都是7位。
因此,例如,如果一行是
The QUICK Brown fox JUMPs OV3R T4E LAZY DoG.
然后我想提取QUICK
和OV3R T4E LAZY
。
这是我到目前为止所做的:
while (<$fh>) { # file handle
my @array = $_ =~ /\b[^a-z]*[A-Z][^a-z]*[A-Z][^a-z]*\b/;
push @bigarray, @array;
}
有没有比[^a-z]*[A-Z][^a-z]*[A-Z][^a-z]*
更优雅的方式?
答案 0 :(得分:1)
看起来你想要所有的单词定义(构造\w
)字符
要查找并允许至少两个大写字母而不是小写字母,您可能不会选择
绕过这个事实,他们必须任选地被帽子包围
和/或数字或下划线。
可能只是匹配你需要的东西。
\b[\d_]*[A-Z]+[\d_]*[A-Z]+[\d_]*\b
扩展:
\b
[\d_]*
[A-Z]+
[\d_]*
[A-Z]+
[\d_]*
\b
啊,结果
输入:
The QUICK Brown fox JUMPs OV3R T4E LAZY DoG.
输出:
** Grp 0 - ( pos 4 , len 5 )
QUICK
-----
** Grp 0 - ( pos 26 , len 4 )
OV3R
-----
** Grp 0 - ( pos 31 , len 3 )
T4E
-----
** Grp 0 - ( pos 35 , len 4 )
LAZY
update - 如果要选择性地匹配由空格分隔的连续部分,
这会奏效。
# (?&two_caps)(?:\s+(?&two_caps))*(?(DEFINE)(?<two_caps>\b[\d_]*[A-Z]+[\d_]*[A-Z]+[\d_]*\b))
(?&two_caps)
(?:
\s+ (?&two_caps)
)*
(?(DEFINE)
(?<two_caps>
\b
[\d_]*
[A-Z]+
[\d_]*
[A-Z]+
[\d_]*
\b
)
)
输出:
** Grp 0 - ( pos 4 , len 5 )
QUICK
** Grp 1 - NULL
---------
** Grp 0 - ( pos 26 , len 13 )
OV3R T4E LAZY
** Grp 1 - NULL
答案 1 :(得分:1)
如果你真的想要那些匹配的运行,可以使用带有零宽度断言的split,然后过滤结果:
while (<DATA>) {
for my $e (split (/(?<=\b)([A-Z0-9_ ]+)(?=\b)/)){
$e =~ s/^\s+|\s+$//g;
print "$e\n" unless ($e =~/^$/ or $e =~ /.*[a-z]/);
}
}
__DATA__
The QUICK Brown fox JUMPs OV3R T4E LAZY DoG.
打印:
QUICK
OV3R T4E LAZY
那么这是如何运作的?
split
会将符合条件的部分与不符合条件的部分分开:
use Data::Dumper;
while (<DATA>) {
print Dumper split (/(?<=\b)([A-Z0-9_ ]+)(?=\b)/);
}
打印:
$VAR1 = 'The';
$VAR2 = ' QUICK ';
$VAR3 = 'Brown';
$VAR4 = ' ';
$VAR5 = 'fox';
$VAR6 = ' ';
$VAR7 = 'JUMPs';
$VAR8 = ' OV3R T4E LAZY ';
$VAR9 = 'DoG.';
然后循环遍历该数组,从每个元素中删除空格,并测试小写字符或空行。
这会导致一行为每行生成数组:
grep { $_ =~ /(?=[A-Z]{2,})^[^a-z]+$/ } map {s/^\s+|\s+$//g; $_} split (/(?<=\b)([A-Z0-9_ ]+)(?=\b)/);
答案 2 :(得分:0)