我對基本的reg-ex很滿意。但是這條用於大量分離的代碼超出了我的知識範圍,並且使用它進行了相當多的搜索也沒有滿足我的好奇心。可以請你花一分鐘向我解釋下面的代碼行嗎?這個正則表達式超出了我的理解「(?=(?: d {3})++(?! d))」
someString.replaceAll("(\\G-?\\d{1,3})(?=(?:\\d{3})++(?!\\d))", "$1,");
我特別不理解正則表達式結構"(?=(?:\d{3})++(?!\d))"
。
感謝很多提前。
我對基本的reg-ex很滿意。但是這條用於大量分離的代碼超出了我的知識範圍,並且使用它進行了相當多的搜索也沒有滿足我的好奇心。可以請你花一分鐘向我解釋下面的代碼行嗎?這個正則表達式超出了我的理解「(?=(?: d {3})++(?! d))」
someString.replaceAll("(\\G-?\\d{1,3})(?=(?:\\d{3})++(?!\\d))", "$1,");
我特別不理解正則表達式結構"(?=(?:\d{3})++(?!\d))"
。
感謝很多提前。
"(?=(?:\d{3})++(?!\d))"
是lookahead assertion。 「
這意味着」只有後跟((我們不需要捕獲的三位數字)重複一次或多次(並且再次重複一次或多次)(後面跟着一個數字)才匹配)「 。請參閱explanation約(?:...)
表示法。它被稱爲非捕獲組,意味着在比賽結束後你不需要參考這個組。
"(\\G-?\\d{1,3})"
是應該實際匹配的部分(但只有滿足上述條件時)。
編輯:我認爲+
必須是特殊字符,否則它只是一個加號。如果它是一個特殊字符(快速搜索暗示it is in Java, too),則第二個是多餘的。
編輯2:感謝Alan Moore,現在很清楚。第二個+
意味着所有格匹配,所以這意味着如果在檢查了儘可能多的3位數組後,它不會發現它們後面沒有非數字,那麼引擎將立即放棄而不是步進一個3數組返回。
這個表達式有一些先進的東西在裏面。首先,最簡單的方法是:\d{3}
意味着三位數字。這些是你的數千人。
那麼:++
是+(它意味着一個或多個)的變體,但佔有慾,這意味着它將吃掉所有的數千個。我不完全確定爲什麼這是必要的。
?:
意味着它是一個非捕獲組 - 我認爲這只是出於性能原因,可以省略。
?=
是一個積極的預測 - 我認爲這意味着它只檢查該組是否存在,但不會計入匹配的字符串 - 這意味着它不會被替換。
?!
是負前瞻 - 我不太明白這一點,但我認爲,這意味着它必須不比賽,這反過來又意味着不能在匹配序列結束另一個數字。這可以確保第一組獲得正確的數字。例如。如果你明白我的意思,10000只能匹配爲10(000)而不是1(000)0。
通過預見,如果我理解正確(我還沒有測試過),只有第一組實際會被替換,因爲它是匹配的。
非常感謝...! – dotwin 2012-04-07 16:40:03
所有格++不是必須的。它使得正則表達式稍微更有效率(正如@Lev所觀察的那樣),但我懷疑你會注意到這種差異。是什麼讓**正確**是'(?!\ d)'。正則表達式*將匹配多個數字組;在'12345678'中,例如,它將首先匹配'12',然後匹配'345'。 – 2012-04-07 19:56:56
對我而言,該正則表達式中最有趣的部分是\G
。我花了一段時間來記住它的用途:防止在小數部分添加逗號(如果有的話)。如果正則表達式是簡單的:
(-?\d{1,3})(?=(?:\d{3})++(?!\d))
...這個數字:
12345.67890
......竟又是:
12,345.67,890
但添加\G
到開始指匹配只能從字符串的開頭或前一場比賽結束的位置開始。所以它不匹配345
,因爲它後面有.
,並且它不匹配67
,因爲它必須跳過某些字符串才能這樣做。所以它正確地返回:
12,345.67890
我知道這不是問題的答案,但我認爲這是值得一提的。
不,第二個'+'不是多餘的;它使第一個「+」[所有格](http://www.regular-expressions.info/possessive.html)。 – 2012-04-07 16:27:23
非常感謝 - 幫助! – dotwin 2012-04-07 16:38:40
對「++」和「+」進行試驗並不會對結果產生任何影響,無論我把整數放在我的整數後面(在java中)。所以我想這實際上只是一個表現問題。 – dotwin 2012-04-07 17:04:15