[英]Perl regex - How to make it less greedy?
如何計算以下字符串中空'字段'的數量? 空字段用-|
表示 或|-|
或者|-
我已經煮熟的正則表達式似乎正在工作,除非我有連續的空字段? 我如何減少貪心?
my $string = 'P|CHNA|string-string|-|-|25.75|-|2562000|-0.06';
my $count = () = ($string=~/(?:^-\||\|-$|\|-\|)/g);
printf("$count\n");
上面的代碼打印2而不是我想要的3。
我完全避免使用正則表達式路由,而是將其視為列表,因為它是一個:
my $count = grep { /^-$/ } split /\|/, $string;
這個問題實際上與貪婪/懶惰沒有任何關系(只適用於像*
或+
這樣的重復運算符)。
問題是兩個空字段緊挨着: |-|-|
。 第一個匹配,但第二個失敗,因為開放|
已被消耗,但因為你在規則^-|
線條標記 ,它與那個不匹配。
我認為更簡單的方法是將輸入分成|
然后查找只包含-
任何字段-
:
my $count = 0;
foreach (split(/\|/,$string)) { if( /^-$/ ) { $count++; } }
由於Perl不支持可變長度的外觀(至少不是我所知),因此實際上沒有辦法用正則表達式來強有力地實現它。 “作弊”的一種方法是附加一個|
在開頭和結尾,你可以成功使用lookbehind / lookahead斷言:
$string = "|$string|";
my $count = () = $string=~/(?<=\|)-(?=\|)/g;
(ikegama的答案下面有一個替代解決方案,確實使用非變量的外觀斷言而不修改字符串,所以當我說“沒有辦法用正則表達式來實現它”時我錯了。道具給ikegama。我仍然認為分裂|
但是,這是解決這個問題的最好方法。)
訣竅是使用lookarounds。 某人的第一次嘗試可能如下:
my $count = () = $string =~ /
(?<\|) # Preceded by "|"
(-)
(?=\|) # Followed by "|"
/xg;
但這不起作用。 上述問題是它不檢測第一個字段或最后一個字段是否為空。 解決這個問題的兩種方法:
my $count = () = "|$string|" =~ /
(?<\|) # Preceded by "|"
(-)
(?=\|) # Followed by "|"
/xg;
要么
my $count = () = $string =~ /
(?<![^|]) # Not preceded by a char other than "|"
(-)
(?![^|]) # Not followed by a char other than "|"
/xg;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.