2011-02-18 97 views
8

這是Mac/OSX相關的問題!在haskell中匹配特定的Unicode字符正則表達式

我有以下三個字符長的Haskell的字符串:

"a\160b" 

我想匹配,更換中間人物像

幾種方法

ghci> :m +Text.Regex 
ghci> subRegex (mkRegex "\160") "a\160b" "X" 
    "*** Exception: user error (Text.Regex.Posix.String died: (ReturnCode 17,"illegal byte sequence")) 
ghci> subRegex (mkRegex "\\160") "a\160b" "X" 
    "a\160b" 

沒有得到期望的結果。

如何修改正則表達式或我的環境以將'\ 160'替換爲'X'?

這個問題似乎有它在輸入的語言環境/編碼中的根。

bash> locale 
LANG= 
LC_COLLATE="C" 
LC_CTYPE="UTF-8" 
LC_MESSAGES="C" 
LC_MONETARY="C" 
LC_NUMERIC="C" 
LC_TIME="C" 
LC_ALL= 

我已經修改了我的.bashrc導出以下ENV-瓦爾:

bash> locale 
LANG="en_US.UTF-8" 
LC_COLLATE="en_US.UTF-8" 
LC_CTYPE="en_US.UTF-8" 
LC_MESSAGES="en_US.UTF-8" 
LC_MONETARY="en_US.UTF-8" 
LC_NUMERIC="en_US.UTF-8" 
LC_TIME="en_US.UTF-8" 
LC_ALL="en_US.UTF-8" 

但這並沒有改變行爲。

+1

你使用的是什麼正則表達式包?這適用於我:`Prelude Text.Regex>:m + Text.Regex Prelude Text.Regex> subRegex(mkRegex「\ 160」)「a \ 160b」「X」 「aXb」 ` – 2011-02-19 00:44:17

+0

`'\ 160 ``是```````,可能會有一些奇怪的神祕原因。Regex.Posix(特別是)不喜歡它,就像將其規範化爲一個普通空間一樣。 – barsoap 2011-02-19 12:26:10

+0

我的第一次嘗試是:regex-base-0.93.2,regex-posix-0.94.2,regex-compat-0.93.1。然後我用Text.Regex.TDFA嘗試了相同的結果。我在MacBook這裏,顯然這個代碼運行在一臺Linux機器上,所以我懷疑底層庫存在一些問題 – 2011-02-21 09:57:31

回答

2

是否有你想使用正則表達式的具體原因,而不僅僅是map

replace :: Char -> Char 
replace '\160' = 'X' 
replace c  = c 

test = map replace "a\160b" == "aXb" 

需要注意的是,如果你想用Unicode字符串的工作,它可能更容易使用text包,它被設計成處理Unicode,而且比String較大的字符串更高效。

5

我能夠通過將我的語言環境設置爲'en_US.UTF-8'來重現您的問題。 (我也使用MacOSX的。)

bash> export LANG=en_US.UTF-8 
bash> ghci     
GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help 
Prelude> :m +Text.Regex 
Prelude Text.Regex> subRegex (mkRegex "\160") "a\160b" "X" 
"*** Exception: user error (Text.Regex.Posix.String died: (ReturnCode 17,"illegal byte sequence")) 

您的區域設置爲「C」就可以解決問題:

bash> export LANG=C 
bash> ghci     
GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help 
Prelude> :m +Text.Regex 
Prelude Text.Regex> subRegex (mkRegex "\160") "a\160b" "X" 
"aXb" 

不幸的是,我沒有解釋,爲什麼語言環境是造成這個問題。