在C中使用带有unicode字符串的正则表达式

时间:2016-12-12 04:11:47

标签: c regex unicode utf-8

我目前正在unicode字符串上使用正则表达式,但我只需要匹配ASCII字符,从而有效地忽略所有unicode字符,直到现在regex.h中的函数工作正常(我在linux上,所以编码是utf8)。但有人可以确认它是否真的可以这样做?或者我需要Unicode上的正则表达式库(如ICU?)

2 个答案:

答案 0 :(得分:2)

UTF-8 is a variable length encoding;一些字符是1个字节,一些是2,其他是3或4.您现在知道每个字符的前缀要读取的字节数。 0表示1个字节,110表示2个字节,1110表示3个字节,11110表示4个字节。

如果您尝试将UTF-8字符串读取为ASCII或任何其他固定宽度编码,那么事情就会非常错误......除非UTF-8字符串只包含1个字节字符,在这种情况下它与ASCII匹配

然而 ,因为UTF-8中没有字节包含空字节,并且没有任何额外字节可以与ASCII混淆,如果你真的只匹配ASCII ,你可能能够逃脱它...但我不推荐它,因为有比POSIX更好的正则表达式选项,它们很容易使用,为什么留下一个隐藏的编码你的代码中的炸弹会让一些傻瓜稍后处理? (注意:那个吸盘可能就是你)

相反,使用像Perl Compatible Regular Expressions(PCRE)这样的Unicode感知正则表达式库。 PCRE2_UTFpcre2_compile标记传递给 MenuItem previousMenuItem; public boolean onNavigationItemSelected(MenuItem item) { if (previousMenuItem != null) { previousMenuItem.setChecked(false); } item.setChecked(true); previousMenuItem = item; if (id == R.id.nav_home) { HomeFragment homeFragment = new HomeFragment(); FragmentManager manager = getSupportFragmentManager(); manager.beginTransaction().replace(R.id.content_fragment, homeFragment, homeFragment.getTag()).commit(); } else if () { // and so on... } } {}。 PCRE正则表达式语法比POSIX正则表达式更强大,更广泛地被理解,并且PCRE具有更多功能。而PCRE is Unicode aware本身就提供了非常方便的C函数的盛宴。

答案 1 :(得分:0)

您需要注意样式和要匹配的文本。

例如,给定表达式a.b

"axb" matches 
"aèb" does NOT match

原因是,在进行UTF-8编码时,è长为两个字节,但是.仅与第一个匹配。

只要您只匹配ASCII字符的序列,就可以保证安全。如果您混合使用ASCII和非ASCII字符,则会遇到麻烦。

您可以尝试将单个UTF-8编码的“字符”与以下内容匹配:

([\xC0-\xDF].|[\xE0-\xEF]..|\xF0...|.)

但这是假设文本编码正确(坦率地说,我从未尝试过)。