###Regexp to match “any character including newline (\n)” ?
因為這個蠻常忘記所以記下來。
即使是用 regexp 抓文件中的 <title>...</title>
這麼單純的事情,還是會遇到例外,像是 http://code.google.com/p/ergoemacs/source/browse/packages/xfrp_find_replace_pairs.el 這個頁面的<title>...</title>
被很神經病地加上了好幾行換行,如果只寫 <title>.*</title>
就會抓不到。因為 regexp 是以「行」為處理單位,所以寫.*
只能抓到「一行裡的所有東西」。
Javascript regexp 抓多行的方法是:1
"(.|\n)*?"
Emacs regexp 大同小異,除了那多到爆炸的反斜線以外:1
"\\(?:.\\|\n\\)*?"
說明(以 Emacs regexp 為例,JS 版差不多。)
\\(PATTERN\\)
表示一個 group- 夾在它中間的
\\|
表示 or- 所以
\\(.\\|\n\\)
表示「任何字元或\n」\\(?:PATTERN\\)
是 group 的一種特殊形式(我不知道其他語言中的 regexp 是否有這種東西),叫做”shy group”。他是一個 group,但是不會被match-string
抓到,也就是說當你只是要「純粹使用 group」而不需要「用match-string
抓 group 內的資料」的話,就可以使用這個。- 最結尾的
?
表示 “non-greedy”,只抓最小符合結果。因為 regexp 的設計都是會抓「最長的符合結果」,可以試試看把這裡的?
去掉,他會一路抓到檔尾。通常我們要抓多行應該都是希望他抓最小符合結果。
我自己目前是用這個方法,但每次寫都覺得這根本是巫術…不過在 Emacs Wiki 上面還有看到 Emacs regexp 有一個更黑魔法的方法:
1 | "[\0-\377[:nonascii:]]*?" |
這個我就不懂為何可以表示「包含換行的所有字元」了…不過看起來反斜線比較少比較乾淨 XD。
更多詳情請看 Regexps - GNU Emacs Manual 和第二頁Regexp Backslash,裡面有完整的 Emacs Regexp 列表。