我可以保留在正则表达式本身中匹配的每个不同字符的数量吗?统计正则表达式通配符匹配的字符串中特定字符的匹配数
假设正则表达式去的样子/>(.*)[^a]+/
我能保留的发生计数,说该集团(.*)
捕获的字符串中的字母p
?
我可以保留在正则表达式本身中匹配的每个不同字符的数量吗?统计正则表达式通配符匹配的字符串中特定字符的匹配数
假设正则表达式去的样子/>(.*)[^a]+/
我能保留的发生计数,说该集团(.*)
捕获的字符串中的字母p
?
AFAIK,你不能。您只能通过圆括号捕获一些组,然后再检查该组捕获的数据的长度。
您将不得不捕获匹配的字符串并单独处理它。
此代码演示
use strict;
use warnings;
my $str = '> plantagenetgoosewagonattributes';
if ($str =~ />(.*)[^a]+/) {
my $substr = $1;
my %counts;
$counts{$_}++ for $substr =~ /./g;
print "'$_' - $counts{$_}\n" for sort keys %counts;
}
输出
' ' - 1
'a' - 4
'b' - 1
'e' - 4
'g' - 3
'i' - 1
'l' - 1
'n' - 3
'o' - 3
'p' - 1
'r' - 1
's' - 1
't' - 5
'u' - 1
'w' - 1
首先一句话:由于*的贪婪,最后[^a]+
将不会匹配超过一个非字符 - 也就是说,你可以放弃+
。
而@mvf表示,您需要捕获通配符匹配的字符串,以便能够对其中的字符进行计数。 Perl正则表达式没有办法返回特定组匹配次数的计数 - 引擎可能会保留数字以支持{,n}
机制,但您无法了解它。
有实验,鸵鸟政策的用我的,(?{ code })
结构...
从man perlre
:
“({}代码?)” 警告:该扩展正则表达式功能被认为是实验性的,可能会更改,恕不另行通知。由于正则表达式引擎中的未来优化效果,因此执行的具有副作用的代码可能不会执行相同版本的 。
如果没有吓跑你,这里才是最重要的 “P” S
my $p_count;
">pppppbca" =~ /(?{ $p_count = 0 })>(p(?{$p_count++})|.)*[^a]+/;
print "$p_count\n";
产生不正确的结果,因为您没有考虑回溯。 (应该为'ppppp'和'pppppa'返回4,但返回5.) – ikegami 2012-08-10 15:19:37
此外,使用在'(?{})'内部在'(?{})'之外声明的'my'变量将导致错误的结果在某些情况下。使用“我们的本地”而不是“我的”。 – ikegami 2012-08-10 15:22:55
这两点都不错。我承认我在写这个例子之前从未使用这个功能。我确实看到了有关使用本地处理回溯的说明。我不知道为什么我发布了这个答案;我不会推荐使用这个,但是认为它足够有趣,可以指出。 – chepner 2012-08-10 15:29:58
以外的正则表达式的数量为例:
my $p_count = map /p/g, />(.*)[^a]/;
自包含:
local our $p_count;
/
(?{ 0 })
>
(?: p (?{ $^R + 1 })
| [^p]
)*
[^a]
(?{ $p_count = $^R; })
/x;
在这两种情况下,你可以很容易地扩大这个数字来计算所有字母。例如,
my %counts;
if (my ($seq = />(.*)[^a]/) {
++$counts{$_} for split //, $seq;
}
my $p_count = $counts{'p'};
沿鲍罗廷的溶液的线去,这里是一个纯的bash之一:
let count=0
testarray=(a b c d e f g h i j k l m n o p q r s t u v w x y z)
string="> plantagenetgoosewagonattributes" # the string
pattern=">(.*)[^a]+" # regex pattern
limitvar=${#testarray[@]} #array length
[[ $string =~ $pattern ]] &&
(while [ $count -lt $limitvar ] ; do sub="${BASH_REMATCH[1]//[^${testarray[$count]}]}" ; echo "${testarray[$count]} = ${#sub}" ; ((count++)) ; done)
从bash的3凝视。0,bash引入了可以通过BASH_REMATCH [n]访问的捕获组。
该解决方案声明将被视为数组的字符[在复杂情况下检出数组声明的declare -a
]。单个字符计数不需要计数变量,不需要构造,而是字符而不是数组。
如果您在上面的代码中包含范围,则此数组声明会执行确切的操作。
testarray=(`echo {a..z}`)
一个if
环的导入将占到0
计数字符的显示。我想尽可能简化解决方案。
耶!五*赞成*你不能*。我必须更努力! – Borodin 2012-08-10 14:52:57
甚至可以在正则表达式中完成。看到我的答案。 – ikegami 2012-08-10 15:27:50
负面的“AFAIK”答案基本上总是一个糟糕的发布选择。如果你不能解释为什么它是不可能的,为什么告诉他们你认为它是? – Mark 2012-08-10 16:31:00