2011-02-18 93 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" 

不幸的是,我没有解释,为什么语言环境是造成这个问题。