在Haskell正则表达式中匹配特定的Unicode字符

8

这是与Mac/OSX相关的问题!

我有一个由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"

没有得到期望的结果。

我需要如何修改正则表达式或我的环境,才能用 'X' 替换 '\160'?

问题似乎源于输入的区域设置/编码。

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文件来导出以下环境变量:

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" - David Powell
'\160'&nbsp,可能是由于某些奇怪的原因,Regex.Posix(特别是)不喜欢它,例如将其规范化为普通空格。 - barsoap
我的第一次尝试是使用:regex-base-0.93.2、regex-posix-0.94.2和regex-compat-0.93.1。然后我尝试了Text.Regex.TDFA,但结果相同。我在MacBook上操作,显然这段代码在Linux机器上运行,所以我怀疑底层库存在问题。 - Axel Tetzlaff
2个回答

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"

很抱歉,我无法解释为什么地区设置会引起这个问题。


1
我之前也遇到了同样的问题,这解决了我的问题。谢谢。但我不知道为什么它没能解决 OP 的问题。 - Joomy Korkut

2

你想使用正则表达式的特定原因是什么,而不是简单地使用map吗?

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

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

请注意,如果您想使用Unicode字符串,使用专门处理Unicode的text包可能更容易,并且对于较大的字符串而言比String更有效率。

1
这只是一个简化的例子,强调这个特定字符的问题。实际的正则表达式会更加复杂。 - Axel Tetzlaff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接