我可以保留正则表达式本身中匹配的每个不同字符的数量吗?
假设正则表达式看起来像/>(.*)[^a]+/
我是否可以对小组p
捕获的字符串中的字母(.*)
进行计数?
答案 0 :(得分:5)
您必须捕获匹配的字符串并单独处理。
此代码演示
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
答案 1 :(得分:5)
在正则表达式之外:
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'};
答案 2 :(得分:3)
AFAIK,你做不到。您只能通过括号捕获某些组,然后检查该组捕获的数据长度。
答案 3 :(得分:3)
按照鲍罗丁的解决方案,这里是一个纯粹的打击:
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
计数字符的显示。我想让解决方案尽可能简单。
答案 4 :(得分:2)
有实验性的,不使用我,(?{ code })
构造......
来自man perlre
:
“(?{code})” 警告:此扩展正则表达式功能被认为是实验性的,可能是 更改,恕不另行执行的具有副作用的代码可能执行不相同 由于未来优化在正则表达式引擎中的影响,从版本到版本。
如果这没有让你害怕,这里有一个计算“p”的数量的例子
my $p_count;
">pppppbca" =~ /(?{ $p_count = 0 })>(p(?{$p_count++})|.)*[^a]+/;
print "$p_count\n";
答案 5 :(得分:0)
首先评论一下:由于*的贪婪,最后[^a]+
将永远不会匹配多个非字符 - 也就是说,您可能会删除+
。
正如@mvf所说,你需要捕获通配符匹配的字符串,以便能够计算其中的字符数。 Perl正则表达式无法返回特定组匹配的次数 - 引擎可能会保留数字以支持{,n}
机制,但是您无法获得它。