2015-12-02 42 views
3

我想修改一個字符串。我正則表達式應該修改數字「 b」字邊界如何影響perl中的輸出?

12365478965412365 

通過將在臺的3 ,由數字轉換成組的3所以輸出的樣子

12,365,478,965,412,365 

我們可以用前瞻,看看-behind實現這一

s/(?<=\d)(?=(\d\d\d)+\b)/\,/g 

但是當我刪除\b

s/(?<=\d)(?=(\d\d\d)+)/\,/g 

我得到儘可能

1,2,3,6,5,4,7,8,9,6,5,4,1,2,365. 

這裏怎麼\b影響看後面的應用位置「」?

是否正則表達式在查看後面的字邊界的末尾進行測試?

+0

'\ b'會影響超前性,而不會影響到這裏的後視。刪除'\ b'時整個比賽會受到影響。 –

+0

您能解釋一下由於\ b而導致字符串從左到右移動時的預見效果如何? – Ullas

+3

你真的可以在[regex101.com的* regex調試器*頁面](https://regex101.com/r/kS4qU6/2)上看到自己。有些人通過粘貼來自該頁面的截圖來回答這些問題會得到瘋狂的點數,但我會敦促你去那裏檢查回溯步驟。 –

回答

4

\b確實匹配單詞之間的邊界。它的寬度是零。從perlre

詞邊界(\b)是具有在其一側上的\w和在它的另一側上的\W(以任一次序)兩個字符之間的點,落計數假想字符字符串的開頭和結尾匹配\W

您要做的事情的問題是,逗號的定位是從右到左的操作 - 您不知道它應該是10,000或100,000,直到您看過字符串中的總數字。

所以我建議,這是容易得多,如果你做一個「直」的正則表達式和向前看符號,而是用reverse做到這一點:

my $str = '12365478965412365';  
my $comma_sep_str = reverse (reverse ($str) =~ s/(\d{3})/$1,/rg); 
print $comma_sep_str; 

扭轉這種局面,組中的三分球從左到右,然後再次反轉。

如果您遇到了正則表達式正在執行的問題,則正常技巧將打開use re 'debug';

我不會重現輸出,因爲它很長。但是現在發生的情況是,該模式使用\b來錨定行結束。

可以多一點清楚地看到這一點,如果你拿走g標誌:

Compiling REx "(?<=\d)(?=(\d\d\d)+\b)" 
Final program: 
    1: IFMATCH[-1] (6) 
    3: POSIXU[\d] (4) 
    4: SUCCEED (0) 
    5: TAIL (6) 
    6: IFMATCH[0] (22) 
    8: CURLYM[1] {1,32767} (19) 
    12:  POSIXU[\d] (13) 
    13:  POSIXU[\d] (14) 
    14:  POSIXU[\d] (17) 
    17:  SUCCEED (0) 
    18: NOTHING (19) 
    19: BOUND (20) 
    20: SUCCEED (0) 
    21: TAIL (22) 
    22: END (0) 
minlen 0 
Matching REx "(?<=\d)(?=(\d\d\d)+\b)" against "12365478965412365" 
    0 <> <1236547896>   | 1:IFMATCH[-1](6) 
            failed... 
    1 <1> <2365478965>  | 1:IFMATCH[-1](6) 
    0 <> <1236547896>   | 3: POSIXU[\d](4) 
    1 <1> <2365478965>  | 4: SUCCEED(0) 
            subpattern success... 
    1 <1> <2365478965>  | 6:IFMATCH[0](22) 
    1 <1> <2365478965>  | 8: CURLYM[1] {1,32767}(19) 
    1 <1> <2365478965>  | 12: POSIXU[\d](13) 
    2 <12> <3654789654>  | 13: POSIXU[\d](14) 
    3 <123> <6547896541>  | 14: POSIXU[\d](17) 
    4 <1236> <5478965412>  | 17: SUCCEED(0) 
             subpattern success... 
            CURLYM now matched 1 times, len=3... 
    4 <1236> <5478965412>  | 12: POSIXU[\d](13) 
    5 <12365> <4789654123> | 13: POSIXU[\d](14) 
    6 <23654> <7896541236> | 14: POSIXU[\d](17) 
    7 <36547> <8965412365> | 17: SUCCEED(0) 
             subpattern success... 
            CURLYM now matched 2 times, len=3... 
    7 <36547> <8965412365> | 12: POSIXU[\d](13) 
    8 <65478> <965412365>  | 13: POSIXU[\d](14) 
    9 <54789> <65412365>  | 14: POSIXU[\d](17) 
    10 <47896> <5412365>  | 17: SUCCEED(0) 
             subpattern success... 
            CURLYM now matched 3 times, len=3... 
    10 <47896> <5412365>  | 12: POSIXU[\d](13) 
    11 <478965> <412365>  | 13: POSIXU[\d](14) 
    12 <4789654> <12365>  | 14: POSIXU[\d](17) 
    13 <47896541> <2365>  | 17: SUCCEED(0) 
             subpattern success... 
            CURLYM now matched 4 times, len=3... 
    13 <47896541> <2365>  | 12: POSIXU[\d](13) 
    14 <478965412> <365>  | 13: POSIXU[\d](14) 
    15 <4789654123> <65>  | 14: POSIXU[\d](17) 
    16 <47896541236> <5>  | 17: SUCCEED(0) 
             subpattern success... 
            CURLYM now matched 5 times, len=3... 
    16 <47896541236> <5>  | 12: POSIXU[\d](13) 
    17 <478965412365> <>  | 13: POSIXU[\d](14) 
             failed... 
            CURLYM trying tail with matches=5... 
    16 <47896541236> <5>  | 19: BOUND(20) 
             failed... 
            CURLYM trying tail with matches=4... 
    13 <47896541> <2365>  | 19: BOUND(20) 
             failed... 
            CURLYM trying tail with matches=3... 
    10 <47896> <5412365>  | 19: BOUND(20) 
             failed... 
            CURLYM trying tail with matches=2... 
    7 <36547> <8965412365> | 19: BOUND(20) 
             failed... 
            CURLYM trying tail with matches=1... 
    4 <1236> <5478965412>  | 19: BOUND(20) 
             failed... 
            failed... 
            failed... 
    2 <12> <3654789654>  | 1:IFMATCH[-1](6) 
    1 <1> <2365478965>  | 3: POSIXU[\d](4) 
    2 <12> <3654789654>  | 4: SUCCEED(0) 
            subpattern success... 
    2 <12> <3654789654>  | 6:IFMATCH[0](22) 
    2 <12> <3654789654>  | 8: CURLYM[1] {1,32767}(19) 
    2 <12> <3654789654>  | 12: POSIXU[\d](13) 
    3 <123> <6547896541>  | 13: POSIXU[\d](14) 
    4 <1236> <5478965412>  | 14: POSIXU[\d](17) 
    5 <12365> <4789654123> | 17: SUCCEED(0) 
             subpattern success... 
            CURLYM now matched 1 times, len=3... 
    5 <12365> <4789654123> | 12: POSIXU[\d](13) 
    6 <23654> <7896541236> | 13: POSIXU[\d](14) 
    7 <36547> <8965412365> | 14: POSIXU[\d](17) 
    8 <65478> <965412365>  | 17: SUCCEED(0) 
             subpattern success... 
            CURLYM now matched 2 times, len=3... 
    8 <65478> <965412365>  | 12: POSIXU[\d](13) 
    9 <54789> <65412365>  | 13: POSIXU[\d](14) 
    10 <47896> <5412365>  | 14: POSIXU[\d](17) 
    11 <478965> <412365>  | 17: SUCCEED(0) 
             subpattern success... 
            CURLYM now matched 3 times, len=3... 
    11 <478965> <412365>  | 12: POSIXU[\d](13) 
    12 <4789654> <12365>  | 13: POSIXU[\d](14) 
    13 <47896541> <2365>  | 14: POSIXU[\d](17) 
    14 <478965412> <365>  | 17: SUCCEED(0) 
             subpattern success... 
            CURLYM now matched 4 times, len=3... 
    14 <478965412> <365>  | 12: POSIXU[\d](13) 
    15 <4789654123> <65>  | 13: POSIXU[\d](14) 
    16 <47896541236> <5>  | 14: POSIXU[\d](17) 
    17 <478965412365> <>  | 17: SUCCEED(0) 
             subpattern success... 
            CURLYM now matched 5 times, len=3... 
    17 <478965412365> <>  | 12: POSIXU[\d](13) 
             failed... 
            CURLYM trying tail with matches=5... 
    17 <478965412365> <>  | 19: BOUND(20) 
    17 <478965412365> <>  | 20: SUCCEED(0) 
             subpattern success... 
    2 <12> <3654789654>  | 22:END(0) 
Match successful! 
Freeing REx: "(?<=\d)(?=(\d\d\d)+\b)" 

12,365478965412365 

因爲環視斷言製成,有一個在正則表達式的這一次迭代很多步驟,因爲什麼它的匹配的第一是:3個或更多由一個「邊界」錨位

(\d\d\d)+\b 

1或多個實例。但是沒有任何東西,所以它只是使用行尾。

這裏不清楚的是\b實際上就好像是$一樣。它充當模式右側的錨點。你的模式必須讀取那麼遠,然後回溯,所以它可以匹配從右邊的(\d\d\d)+。沒有這一點,你的模式不錨定,因此匹配任何4位子字符串 - 但因爲它不消耗,它會匹配除了最後3以外的每個數字。(這是發生了什麼)

您的模式工作如果您使用$,也是如此。希望這能讓它更清楚發生了什麼?

my $str = '12365478965412365';  
$str =~ s/(?<=\d)(?=(\d\d\d)+$)/\,/g;  
print $str; 
+0

是的..這將大大簡化任務..感謝很多的方法。 – Ullas

+1

非常感謝您的詳細解釋 – Ullas

相關問題