精華區beta RegExp 關於我們 聯絡資訊
沒想到PTT也有地方可以討論RegExp耶 以後又多一個常逛的版了^^ 前一陣子寫RegExp 一直試不出來要如何寫才能讓中文和英文區隔出來 比如說: 我叫hunterfish我現在在RegExp版 要變成 我叫 hunterfish 我現在在 RegExp 版 我原本想法是想碰到英文字為首和結尾就自動塞入一個空隔 不知道這種寫法要怎樣去實作 還有其他更好的寫法嗎? 先謝謝這邊的大大們了!! -- -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 61.229.235.107
LPH66:可以用[A-Za-z]+去抓出一串英文字 11/08 22:56
LPH66:不過如果字碼是big-5就很麻煩了...utf-8就沒有問題 11/08 22:57
hunterfish:對不起,我還是不太懂耶 11/08 22:59
> -------------------------------------------------------------------------- < 作者: MichaelHsin (BBS之蟲) 看板: RegExp 標題: Re: [問題] 中英文區分 時間: Thu Nov 8 23:38:34 2007 ※ 引述《hunterfish (可愛的阿宏)》之銘言: : 沒想到PTT也有地方可以討論RegExp耶 : 以後又多一個常逛的版了^^ : 前一陣子寫RegExp : 一直試不出來要如何寫才能讓中文和英文區隔出來 : 比如說: : 我叫hunterfish我現在在RegExp版 : 要變成 : 我叫 hunterfish 我現在在 RegExp 版 : 我原本想法是想碰到英文字為首和結尾就自動塞入一個空隔 : 不知道這種寫法要怎樣去實作 : 還有其他更好的寫法嗎? : 先謝謝這邊的大大們了!! 以 perl 為例,配合 zero-width look-(ahead|behind): ===== # $w 和 $n 只是方便閱讀後面的 regex,如果不喜歡的話直接代換在裡面也是可以 # 「英文字」的定義 $w = "-A-Za-z0-9_"; # $w 加上空白 $n = "$w "; # input: $str # 把「英文字」的前面加上空白,如果有空白或是行首就不加 $str =~ s/(?<=[^$n])([$w]+)/ $1/g; # 把「英文字」後面加上空白,如果已有空白或是行尾/換行符號就不加 $str =~ s/([$w]+)(?=[^$n])/$1 /g; ===== 有些小細節像 $w, $n 裡的 "-" 為什麼要放最前面,想一下它代換進什麼地方應該 就懂了 :p 另外,因為 Big5 的第二個字元(low-byte)範圍包含了 $w 定義的字元,會導致上面 的 [$w]+ 會把 Big5 的 low-byte 也包進來,而導致空白加在不對的地方,所以要 另外處理。UTF-8 則是沒這個問題。 -- 芸曰:「今世不能,期以來世。」 余曰:「來世卿當作男,我為女子相從。」 芸曰:「必得不昧今生,方覺有情趣。」 余笑曰:「幼時一粥猶談不了;若來世不昧今世,合巹之夕,細談隔世,更無合 眼時矣。」 -- 沈復 《浮生六記》 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.112.30.55 > -------------------------------------------------------------------------- < 作者: MichaelHsin (BBS之蟲) 看板: RegExp 標題: Re: [問題] 中英文區分 時間: Fri Nov 9 00:14:26 2007 ※ 引述《MichaelHsin (BBS之蟲)》之銘言: : 另外,因為 Big5 的第二個字元(low-byte)範圍包含了 $w 定義的字元,會導致上面 : 的 [$w]+ 會把 Big5 的 low-byte 也包進來,而導致空白加在不對的地方,所以要 : 另外處理。UTF-8 則是沒這個問題。 應付 Big5 的解法: 1. 正解:使用 Big5-aware regex engine 例如 perl 可以 use encoding 2. 惡搞解:正解不能用的時候 隨手想了一個,用 s///e 達成: ===== # 這是 strict Big5-1985 的定義範圍 # 要取廣義的 Big5-Eten 或是 Big5-UAO 可修改 $bh 和 $bl # Big5 high-byte $bh = "\\xa1-\\xfe"; # Big5 low-byte $bl = "\\xa1-\\xfe\\x40-\\x7e"; # greedy 取最長的連續 Big5 string,及其前、後一或零個字元,分別為 $2, $1, $3 # 如果 $1 不是空白,就在 $1 和 $2 間加上一個空白 # 如果 $3 不是空白,就在 $2 和 $3 間加上一個空白 # 兩行請自行接上 $str =~ s/(.?)((?:[$bh][$bl])+)(.?)/ $1 . (1 ne " " ? " " : "") . $2 . ($3 ne " " ? " " : "") . $3/ge; ===== 連同上篇,雖然是用 perl 寫的,但應該都可用各種語言/環境提供的 regex engine 做到同樣的效果。 -- 芸曰:「今世不能,期以來世。」 余曰:「來世卿當作男,我為女子相從。」 芸曰:「必得不昧今生,方覺有情趣。」 余笑曰:「幼時一粥猶談不了;若來世不昧今世,合巹之夕,細談隔世,更無合 眼時矣。」 -- 沈復 《浮生六記》 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.112.30.55
MichaelHsin:其實這兩篇用的 zero-width look-(ahead|behind) 和 11/09 00:18
MichaelHsin:s///e 的方法都可以互換 :Qoo 11/09 00:18
buganini:還可以先轉成UTF-8處理完在轉回去XD 11/09 06:43
godfat:推先轉碼 XDDD 11/09 13:25
MichaelHsin:轉碼的話,標準 Big5-1985 好解決,要是資料有 UAO 之 11/09 17:56
MichaelHsin:類的東西,目前好像還沒有現成的轉碼器可以轉 UAO 的 11/09 17:57
> -------------------------------------------------------------------------- < 作者: LiloHuang (相見不如懷念) 看板: RegExp 標題: Re: [問題] 中英文區分 時間: Fri Nov 9 22:50:16 2007 # 只有針對 Big5 不能使用於 UTF-8 $_ = '我叫hunterfish我現在在RegExp版'; s/((?:[\xA1-\xF9][\x40-\x7E\xA1-\xFE])+|\w+)(?<!$)/$1 /g; print; -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.114.71.40
twico:威! 11/09 23:05
freesamael:reg exp 有時候看起來真的會有種外星文字的感覺XD 11/09 23:08
> -------------------------------------------------------------------------- < 作者: cutecpu (可愛中央處理器) 看板: RegExp 標題: Re: [問題] 中英文區分 時間: Sat Nov 10 01:38:38 2007 ※ 引述《LiloHuang (相見不如懷念)》之銘言: : # 只有針對 Big5 不能使用於 UTF-8 : $_ = '我叫hunterfish我現在在RegExp版'; : s/((?:[\xA1-\xF9][\x40-\x7E\xA1-\xFE])+|\w+)(?<!$)/$1 /g; : print; $_='RegExp'; output變成:RegEx p -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 218.167.233.111 > -------------------------------------------------------------------------- < 作者: LiloHuang (相見不如懷念) 看板: RegExp 標題: Re: [問題] 中英文區分 時間: Sat Nov 10 09:46:15 2007 ※ 引述《cutecpu (可愛中央處理器)》之銘言: : $_='RegExp'; : output變成:RegEx p 那就改這樣吧 別用 zero width negative look behind 了 而且前一篇應該用 look ahead 比較正確... Sorry 囉 XD $_ = '我叫hunterfish我現在在RegExp版'; s/((?:[\xA1-\xF9][\x40-\x7E\xA1-\xFE])+|\w+)/$1 /g,chop; print; -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.114.71.40
qerter:chomp ? 11/13 23:03
LiloHuang:chop 與 chomp 兩者功用不同,請自行查閱 perldoc 11/14 19:11