如果我想使用C++11的正则表达式处理Unicode字符串,能否直接使用UTF-8编码的char*,还是必须将其转换为wchar_t*类型的字符串?
您需要测试编译器和所使用的系统,但理论上,如果您的系统有UTF-8语言环境,则应该会支持。在Clang/OS X上,以下测试对我返回了true。
bool test_unicode()
{
std::locale old;
std::locale::global(std::locale("en_US.UTF-8"));
std::regex pattern("[[:alpha:]]+", std::regex_constants::extended);
bool result = std::regex_match(std::string("abcdéfg"), pattern);
std::locale::global(old);
return result;
}
注意:这是在一个UTF-8编码的文件中编译的。
为了安全起见,我还使用了明确十六进制版本的字符串。也可以工作。
bool test_unicode2()
{
std::locale old;
std::locale::global(std::locale("en_US.UTF-8"));
std::regex pattern("[[:alpha:]]+", std::regex_constants::extended);
bool result = std::regex_match(std::string("abcd\xC3\xA9""fg"), pattern);
std::locale::global(old);
return result;
}
更新:对我而言test_unicode()
仍然可用。
$ file regex-test.cpp
regex-test.cpp: UTF-8 Unicode c program text
$ g++ --version
Configured with: --prefix=/Applications/Xcode-8.2.1.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode-8.2.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
u8"abcdéfg"
,则无需将源代码保存为UTF-8格式。 - R. Martinho Fernandesu8""
并不是必须的)。test_unicode()
和test_unicode2()
都返回false
(g++ -std=c++11 *.cc && ./a.out
)。无论ideone使用什么,都会产生相同的结果。 - jfsC++11的正则表达式对UTF-8的支持还算可以,但只是最基本的支持。如果你想要完整的Unicode正则表达式支持来处理UTF-8字符串,最好使用直接支持该功能的库,例如http://www.pcre.org/。
是的,这是UTF-8编码的设计原则。如果将字符串视为字节数组而不是代码点数组,则子字符串操作应该可以正常工作。
请参见此处的FAQ#18:http://www.utf8everywhere.org/#faq.validation,了解如何在此编码设计中实现此目标。
我有一个使用案例,需要在查找笛卡尔坐标时处理可能的Unicode字符串,这个示例展示了我如何按照建议使用std::wregex
和std::wstring
来处理解析模块中的可能的Unicode字符。
static bool isCoordinate(std::wstring token)
{
std::wregex re(L"^(-?[[:digit:]]+)$");
std::wsmatch match;
return std::regex_search(token, match, re);
}
int wmain(int argc, wchar_t * argv[])
{
// Testing against not a number nor unicode designation
bool coord = ::isCoordinate(L"أَبْجَدِيَّة عَرَبِيَّة中文");
if (!coord)
return 0;
return 1;
}