推 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