在 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++库。
std::regex
构造函数的标志之一是 collate,它指定:
格式为"[a-b]"的字符范围将区分区域设置。
有关全面的解释,请参阅正则表达式范围和区域设置:一个漫长悲伤的故事:
但是,该标准改变了范围表达式的解释。在"C"和"POSIX"区域设置中,像"[a-dx-z]"这样的范围表达式仍然等效于"[abcdxyz]",如ASCII。但在这些区域设置之外,排序被定义为基于排序规则顺序。
那是什么意思?在许多区域设置中,"A"和"a"都小于"B"。换句话说,这些区域设置按字典顺序对字符进行排序,"[a-dx-z]"通常不等同于"[abcdxyz]";相反,它可能等同于"[ABCXYabcdxyz]",例如。
这一点需要强调:许多文献教导你应该使用"[a-z]"来匹配小写字符。但在具有非 ASCII 语言环境的系统上,这也匹配除"A"或"Z"之外的所有大写字符!这一直造成混乱,甚至一直持续到二十一世纪。
对我来说
,这表明默认情况下,
std::regex
不是(完全)区域设置感知的。
差一点。
在修改后的 ECMAScript 正则表达式语法中,它说:
字符类
。
C++中每个字符类转义的确切含义是根据依赖于语言环境的命名字符类来定义的,而不是像 ECMAScript 那样显式列出可接受的字符。
换句话说,它对字符类使用当前的全局区域设置,如[:alpha:]
。
是否可以读取 UTF-8 字符串并将其存储在普通
std::string
中,并且只使用[:w:]
和[:punct:]
等正则表达式类?具体来说,[:w:]
可能是一个问题。[:punct:]
并不重要。
不知道std::string
的内容是什么编码,它们可能是 UTF-8 或任何其他编码。
你需要将一个std::string
解码为std::wstring
,一种方法是使用std::codecvt_utf8提供的设施,然后使用std::wregex
。