devnagari unicode文本的正确区域设置



以下输出错误。应该只返回1个单词,而不是2个

$ echo 'उद्योजकता' |  grep -o -E 'w+'
उद
योजकता

我被告知这是由于区域设置的原因。我在2台不同的服务器上用2个不同的O/S进行了检查,结果是一样的。

Ubuntu

$ locale
LANG=C.UTF-8
LANGUAGE=
LC_CTYPE="C.UTF-8"
LC_NUMERIC="C.UTF-8"
LC_TIME="C.UTF-8"
LC_COLLATE="C.UTF-8"
LC_MONETARY="C.UTF-8"
LC_MESSAGES="C.UTF-8"
LC_PAPER="C.UTF-8"
LC_NAME="C.UTF-8"
LC_ADDRESS="C.UTF-8"
LC_TELEPHONE="C.UTF-8"
LC_MEASUREMENT="C.UTF-8"
LC_IDENTIFICATION="C.UTF-8"
LC_ALL=

AWS EC2

# locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

我不确定应该选择哪个区域设置才能使Devnagari unicode文本只在空格处中断。

编辑以添加:如果机器上的grep支持Perl兼容的正则表达式(PCRE(,则可以使用类似的方法。例如,在AmazonLinux上应该是这样。

echo 'उद्योजकता' |grep -o -P '[wpLpM]+'

其将匹配";单词";字符OR";字母";代码点OR";标记";代码点,

echo 'उद्योजकता' |grep -o -P '(*UCP)[wpM]+'

这将启用unicode字符属性(UCP(匹配,以便w匹配所有字母和数字,无论脚本如何,但您仍然必须在模式中包括pM,因为\w根本不匹配"标记";grep中的点--它们不是字母数字代码点。

小心以上内容!我不知道梵文,所以我不知道是否应该考虑所有这些";标记";字符作为一个单词的一部分以达到您的目的。可能是更窄的集合,如Mn(用于非间距标记(更适合您的需求,或者可能只有几个特定的点可以包括,在这种情况下,您需要在图案中单独选择它们。


在过去,w只是指[A-Za-z0-9_]。它是以ASCII和C代码为中心的。今天,在典型的解释中,它仍然意味着";字母数字和下划线";,其可以根据地区而变化。

你说输出是";错误";,但我恐怕"错误的";取决于您使用的正则表达式引擎。因此,即使您使用";grep";,问题是哪个grep,在哪个操作系统上,等等。

据我所知,您的输入包含0x094d,这是而不是a";字母";,根据unicode字符定义(至少,不是根据上面的链接(。它是一个";标记";。

一个Unicode";文件";(推荐(,包括发动机如何定义";\w";为了实现Unicode智能,它确实建议在匹配中包含Mark代码点。因此,从这个意义上说,你的期望是自然的。然而,你可以从同一个链接中看到,没有办法做到这一点,也没有办法同时严格遵守POSIX,这是许多正则表达式引擎想要做到的

维基百科指出,有一些引擎支持Unicode属性定义,但总的来说,grep不会这么做。我对这些引擎(ruby等(不够熟悉,无法确切说明如何在命令行上尝试与grep相同的操作。

grep的macOS(11.2.3(手册页底部有这样的注释:

BUGS
The grep utility does not normalize Unicode input, so a pattern containing composed characters will not match decomposed input, and vice versa.

如果您可以单独使用Devnagari文本的解决方案,这些会有所帮助。根据维基百科,Unicode的范围是U+0900U+097f。因此,如果您的shell支持$'...'表单,则可以使用:

$ echo 'उद्योजकता' | grep -oE  $'[u0900-u097f]+'
उद्योजकता

如果PCRE可用:

$ echo 'उद्योजकता' | grep -oP '[x{900}-x{97f}]+'
उद्योजकता

使用ripgrep可以获得更好的Unicode支持。

$ echo 'उद्योजकता' | rg -o 'w+'
उद्योजकता

最新更新