以下输出错误。应该只返回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+0900
到U+097f
。因此,如果您的shell支持$'...'
表单,则可以使用:
$ echo 'उद्योजकता' | grep -oE $'[u0900-u097f]+'
उद्योजकता
如果PCRE可用:
$ echo 'उद्योजकता' | grep -oP '[x{900}-x{97f}]+'
उद्योजकता
使用ripgrep可以获得更好的Unicode支持。
$ echo 'उद्योजकता' | rg -o 'w+'
उद्योजकता