std :: regex总是能识别语言环境吗?

时间:2018-01-12 09:17:31

标签: c++ c++11

std::basic_regex引用中,std::regex的构造函数的一个标志是collate,它指定:

  

“[a-b]”形式的字符范围将区域敏感。

对我来说,这表明std::regex默认情况下不是(完全)区域设置感知的。我找不到任何声称明确 可识别区域设置的内容,但后来我们std::regex_traits表示存在某些区域设置感知继续。

std::regex区域设置感知的范围是什么? 是否可以读取UTF-8字符串并将其存储在普通std::string中,并且只使用[:w:][:punct:]等正则表达式类?具体来说,[:w:]可能是个问题。 [:punct:]并不重要。

这适用于必须适用于MacOS(具有UTF-8语言环境)和Windows(据我所知,并非如此)的C ++库。

1 个答案:

答案 0 :(得分:2)

  

std::regex的构造函数的一个标志是collat​​e,它指定:

     
    

形式的字符范围" [a-b]"将是区域敏感的。

  

有关综合说明,请参阅Regexp Ranges and Locales: A Long Sad Story

  

但是,标准改变了范围表达式的解释。在" C"和" POSIX" locales,像'[a-dx-z]'这样的范围表达式仍然等同于'[abcdxyz]',就像在ASCII中一样。但在这些区域之外,排序被定义为基于整理顺序。

     

这是什么意思?在许多语言环境中,'A'和'a'都小于'B'。换句话说,这些语言环境按字典顺序对字符进行排序,'[a-dx-z]'通常不等同于'[abcdxyz]';相反,它可能等同于'[ABCXYabcdxyz]',例如。

     

这一点需要强调:很多文献教导你应该使用'[a-z]'来匹配小写字符。但是在具有非ASCII语言环境的系统上,这也匹配除“A”或“Z”之外的所有大写字符!这是一个混乱的连续原因,甚至进入二十一世纪。

  

对我来说,这表明std::regex默认情况下不是(完全)区域设置感知的。

不完全。

Modified ECMAScript regular expression grammar中说:

  

角色类

     

...

     

C ++中每个字符类转义的确切含义是根据与语言环境相关的命名字符类定义的,而不是像在ECMAScript中那样显式列出可接受的字符。

换句话说,它使用当前的全局语言环境来处理像[:alpha:]这样的字符类。

  

是否可以读取UTF-8字符串并将其存储在普通std::string中,并且只使用[:w:][:punct:]等正则表达式类?具体来说,[:w:]可能是个问题。 [:punct:]并不重要。

不知道std::string的内容编码是什么,它们可以是UTF-8或任何其他编码。

您需要将std::string解码为std::wstring,一种方法是使用std::codecvt_utf8提供的设施,然后使用std::wregex