我可以保留在正則表達式本身中匹配的每個不同字符的數量嗎?統計正則表達式通配符匹配的字符串中特定字符的匹配數
假設正則表達式去的樣子/>(.*)[^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