繁体   English   中英

使用UTF-8在非ASCII字符上运行Ascii正则表达式

[英]Running Ascii regex over non-ASCII characters with UTF-8

#include <boost/regex.hpp>

#include <string>
#include <vector>
#include <iostream>

int main(int argc, char* argv[]) {

    std::string text = argv[1];
    std::string patterns = argv[2];

    boost::regex regex = boost::regex(patterns);

    boost::smatch match;

    std::cout << boost::regex_search(text, match, regex) << std::endl;    
}

如果我通过输入hello¿ ¿ (包含UTF-8编码的非ASCII字符)运行程序,它返回0即未找到,但是如果我通过输入hel√√运行它(再次包含非ascii)它返回1,即找到。

我的问题:当运行utf字符时, boost::regex (即ascii版本)的预期行为是什么?


编辑:感谢所有的评论,我仍然感兴趣的是为什么输出正好1,因为文本和正则表达式都包含非ascii字符。 我的猜测是字节被解释为ascii,因此它们匹配。

  1. 在ASCII字符串上使用正则表达式,就是使用“bytes”来查找模式。
    在UTF-8字符串上使用正则表达式是关于在“多字节”序列上使用正则表达式,其中序列表示Unicode代码点。

    因此,正则表达式应用于Unicode字符串,其编码具有每个字符可变的字节数。

    UTF-8字符串包含1到4个字节的多字节序列,表示Unicode“字符”。 在UTF-8中,只有ASCII 7位字符是1字节“宽”。

    因此 - 在UTF-8编码的字符串上使用ASCII正则表达式引擎 ,忽略UTF-8编码字符串中的多字节序列,并导致逐字节匹配模式。 在UTF-8编码的字符串上使用此ASCII正则表达式引擎的结果无效

    请查看http://utfcpp.sourceforge.net

    要使正则表达式处理UTF-8编码的字符串,您必须...

    • 有UTF-8字符串迭代器可用于正则表达式,或
    • 使用std::codecvt_utf8结合临时设置全局语言环境以使正则表达式工作,或者
    • 必须将UTF-8编码的字符串转换为UTF-16编码的字符串,以便与Unicode正则表达式引擎一起使用 - 基于std :: wstring。
  2. regex_search函数在匹配时返回布尔值和true
    在您的情况下,ASCII正则表达式模式匹配UTF-8编码字符串的一部分,该字符串被无效地解析为ASCII字符串 - 正如您所假设的那样!
    如果您使用UTF-8编码的字符串中的英文文本,则可以安全地使用ASCII正则表达式引擎。 保留ASCII 7位范围,使得ASCII正则表达式引擎的结果不可靠。

这是一个错误,而不是一个功能:我在一个更好的系统上尝试了你的例子(在Windows MinGW上的g ++ 4.9.2),一切都很顺利:

#include <iostream>
#include <string>
#include <regex>
int main()
{ std::string text ="hello¿"; // or "hello√"
  std::string patterns ="¿";  // or "√"
  std::regex regex = std::regex(patterns);
  std::smatch match;
  std::cout << std::regex_search(text, match, regex) << std::endl;
}

输出:

1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM