簡體   English   中英

Perl正則表達式 - 如何減少貪心?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM