My RegEx Library

5. 刪除程序中的各種注釋

  • 首先考慮到在字符串中可能存在注釋的文本腾窝,但是這些注釋我們是不需要刪除的卷员,
  • 所以可以加一個分支再匹配字符串
  • 這時當匹配字符串開始時候盈匾,就會一直匹配到字符串結(jié)束
  • 然后下次匹配的時候,是在字符串尾部繼續(xù)應(yīng)用正則表達式毕骡,所以不會匹配到內(nèi)部
  • 同理注釋中字符串也不算程序中的字符串威酒,因為在更前的位置,已經(jīng)被當成注釋給匹配了
  • 如果既不是字符串也不是注釋挺峡,傳動裝置才會驅(qū)動到下一個位置繼續(xù)嘗試

匹配注釋的表達式

  • 多行注釋: /\*[\s\S]*?\*/
  • 單行注釋: //.*+

匹配字符串的表達式

  • 單引號或雙引號 字符串: (["'])(?:(?!\1)[^\n\\])*+(?:\\.(?:(?!\1)[^\n\\])*+)*+\1

所以整個表達式可以寫成

  • (["'])(?:(?!\1)[^\n\\])*+(?:\\.(?:(?!\1)[^\n\\])*+)*+\1|/\*[\s\S]*?\*/|//.*+

表達式的順序是不重要的,但是文本中那種內(nèi)容更多可能改變表達式的順序卻可以提高效率
如果要刪除注釋担钮,則替換的時候替換成字符串匹配到的內(nèi)容即可橱赠,如果注釋匹配為空,則無影響箫津,如果字符串為空狭姨,則注釋將被刪除

regex: ((["'])(?:(?!\2)[^\n\\])*+(?:\\.(?:(?!\2)[^\n\\])*+)*+\2)|/\*[\s\S]*?\*/|//.*+
replacement: $1


不使用忽略優(yōu)先量詞和環(huán)視來匹配注釋的更高效版本

  • regex: ((["'])(?:(?!\2)[^\n\\])*+(?:\\.(?:(?!\2)[^\n\\])*+)*+\2)|/\*[^*]*+(?:\*++[^/*][^*]*+)*+\*++/|//.*+
  • replacement: $1

因為在java中測試宰啦,匹配多行注釋使用這種辦法效率更高,而匹配單引號和雙引號不使用多選分支效率更高


進一步優(yōu)化

  • 在匹配非字符串和注釋的時候饼拍,這些內(nèi)容不能被匹配赡模,表達式只能依次嘗試完所有的分支報告當前位置失配,然后由傳動裝置驅(qū)動到下一個位置师抄,因為java采用的是傳統(tǒng)型nfa引擎漓柑,表達式主導(dǎo),所以可以自己控制表達式的匹配叨吮,
  • 在第一個分支加入匹配其他字符的表達式: [^'/"]+, 之所以不使用星號量詞是因為*總是能夠匹配成功辆布,而當匹配到注釋開始時,其不能匹配任何文本茶鉴,也能報告成功锋玲,下一次迭代的時候,傳動裝置就會從下一個位置繼續(xù)開始匹配涵叮,這將會把注釋當成其他內(nèi)容匹配而保留下來惭蹂。

([^/'"]++|(["'])(?:(?!\2)[^\n\\])*+(?:\\.(?:(?!\2)[^\n\\])*+)*+\2)|/\*[^*]*+(?:\*++[^/*][^*]*+)*+\*++/|//.*+

  • 然而當匹配完字符串后,接下來很可能又是其他字符割粮,所以可以在其后添加匹配其他字符的表達式: [^'/"]+盾碗,因為也可能后面存在的是注釋,如
String test = "test"/*middle comments*/;

所以我們應(yīng)該使用星號量詞: [^'/"]*
得到最后的表達式
([^/'"]++|(["'])(?:(?!\2)[^\n\\])*+(?:\\.(?:(?!\2)[^\n\\])*+)*+\2[^/'"]*+)|/\*[^*]*+(?:\*++[^/*][^*]*+)*+\*++/|//.*+


可能還會考慮到優(yōu)化

  • 可以把其他字符當作普通字符穆刻,注釋和字符串當作特殊字符
  1. normal: [^/'"]
  2. special: (?:((["'])(?:(?!\2)[^\n\\])*+(?:\\.(?:(?!\2)[^\n\\])*+)*+\2)|(?:/\*[^*]*+(?:\*++[^/*][^*]*+)*+\*++/|//.*+))
  • 注釋非捕獲置尔,其他和字符串捕獲,得到:

  • regex: ([^/'"]*+)(?:(?:((["'])(?:(?!\3)[^\n\\])*+(?:\\.(?:(?!\3)[^\n\\])*+)*+\3)|(?:/\*[^*]*+(?:\*++[^/*][^*]*+)*+\*++/|//.*+))([^/'"]*+))*+
  • replacement: $1$2$4

但實際上這是不正確的氢伟,$2$4捕獲的文本存在于量詞限定之中榜轿,其捕獲的文本時刻在發(fā)生改變,每次都為最后一次應(yīng)用匹配到的文本朵锣。

4. 匹配程序中的字符串

  • 程序中的字符串分兩種谬盐,單引號字符串和雙引號字符串
  1. 匹配雙引號字符串: "(?:[^\\"\n]|\\.)*+"
  2. 匹配單引號字符串: '(?:[^\\'\n]|\\.)*+'
  • 消除循環(huán)
  1. "[^\\"\n]*+(?:\\.[^\\"\n]*+)*+"
  2. '[^\\'\n]*+(?:\\.[^\\'\n]*+)*+'

  • 可以用一個正則表達式來匹配單引號字符串和雙引號字符串
    (["'])(?:(?!\1)[^\n\\]|\\.)*+\1
    經(jīng)測試合并后的表達式相比于多選分支具有更高的效率
  • 消除循環(huán)
    (["'])(?:(?!\1)[^\n\\])*+(?:\\.(?:(?!\1)[^\n\\])*+)*+\1

3. 單純匹配程序多行注釋

special部分匹配的內(nèi)容是normal不能匹配的疑似結(jié)束tag的內(nèi)容,但是special又不會匹配掉結(jié)束tag诚些,所以這里可以把諾干個****...[^/*]當作special飞傀,****.../當作結(jié)束tag,之所以不能把*[^/]當作special诬烹,*/當作結(jié)束tag砸烦,是因為如果結(jié)束是**/,這樣的字符绞吁,會造成special匹配**幢痘,/被normal部分匹配掉.

不使用忽略優(yōu)先量詞與環(huán)視

  • opening: /\*
  • normal: [^*]
  • special: \*+[^*/]
  • closing: \*+/
    regex1: /\*[^*]*+(?:\*++[^/*][^*]*+)*+\*++/
  • opening: /\*
  • normal*: [^*]*\*+
  • special: [^*/]
  • closing: /
    regex2: /\*[^*]*+\*++(?:[^/*][^*]*+\*++)*+/

regex3: /\*(?:(?!\*/)[\s\S])*+\*/
regex4: /\*[\s\S]*?\*/

  • 在java中的效率比較
    1, 2 > 4 > 3

2. 匹配CVS文件的內(nèi)容

  • 匹配hsdh,"gsg ""gsasg""ga",,gs,"",asghs
  • 得到 hsdh"gsg ""gsasg""ga"家破,颜说,gs购岗,""asghs

regex1: (?:(?<=,)|^)(?:[^\n,]*+|"(?:[^\n"]|"")*+")
regex2: (?:(?<=,)|^)(?:[^\n,]*+|"[^\n"]*+(?:""[^\n"]*+)*+")

1. 為數(shù)值添加逗號

問題:

  • 將類似298444215替換成298,444,215

解決辦法:

  1. 前面要存在數(shù)字——使用(?<=\d)
  2. 后面要存在數(shù)字且是3的整倍數(shù)——(?=(?:\d\d\d)+$)

regex: (?<=\d)(?=(?:\d{3})++$)
replacement: ,

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末门粪,一起剝皮案震驚了整個濱河市喊积,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌玄妈,老刑警劉巖乾吻,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異措近,居然都是意外死亡溶弟,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門瞭郑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辜御,“玉大人,你說我怎么就攤上這事屈张∏苋ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵阁谆,是天一觀的道長碳抄。 經(jīng)常有香客問我,道長场绿,這世上最難降的妖魔是什么剖效? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮焰盗,結(jié)果婚禮上璧尸,老公的妹妹穿的比我還像新娘。我一直安慰自己熬拒,他們只是感情好爷光,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澎粟,像睡著了一般蛀序。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上活烙,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天徐裸,我揣著相機與錄音,去河邊找鬼啸盏。 笑死重贺,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播檬姥,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼粉怕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贫贝,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎稚晚,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體客燕,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡鸳劳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了也搓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡幔摸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出颤练,到底是詐尸還是另有隱情既忆,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布嗦玖,位于F島的核電站患雇,受9級特大地震影響踏揣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捞稿,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望娱局。 院中可真熱鬧,春花似錦衰齐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽澈蟆。三九已至墨辛,卻和暖如春趴俘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寥闪。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留疲憋,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓嗽元,卻偏偏與公主長得像,于是被迫代替她去往敵國和親剂癌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理佩谷,服務(wù)發(fā)現(xiàn)监嗜,斷路器谐檀,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 版權(quán)歸作者所有,任何形式轉(zhuǎn)載請聯(lián)系作者裁奇。 作者:小山 來源: 喜新厭舊的小唐搬了新家桐猬,在搬家前,他把家里的物品刽肠,連...
    小山的隨思錄閱讀 246評論 0 2
  • 一樓到十樓的每層電梯門口都放著一顆鉆石,鉆石大小不一惫撰。你乘坐電梯從一樓到十樓,每層樓電梯門都會打開一次厨钻,只能拿一次...
    博格體閱讀 1,017評論 0 0
  • 來到公司近兩周,所在部門正好組織架構(gòu)中夯膀,人不多團隊是十人左右,雖人少但也得分組分管诱建,今天就談?wù)剬λ睦斫猓日f說部...
    易錦風(fēng)閱讀 1,378評論 0 0