正则表达式匹配 Unicode 'Punctuation'类别 c++

Regex match Unicode 'Punctuation' category c++

本文关键字:类别 c++ Punctuation 正则表达式 Unicode      更新时间:2023-10-16

根据各种文档,为了匹配任何标点符号,我需要使用"p{p}"模式

#include <regex>
#include <string>
...
std::string str = "Hello'"#%&!.:,?¿World";
std::regex re("\p{P}", std::regex::extended );
str = std::regex_replace(str, re, " ");

但是当我这样做时,我得到一个错误,所以我的问题是,我如何匹配所有标点符号p{p}?

在我的环境中,您的程序的wchar_t版本按预期工作:

#include <regex>
#include <string>
#include <iostream>
#include <locale>
int main ()
{
    std::locale::global(std::locale(""));
    std::wstring str =L"Hello'"#%&!.:,?¿World";
    std::basic_regex<wchar_t> re(L"[[:punct:]]", std::regex::extended );
    str = std::regex_replace(str, re, L" ");
    std::wcout << str << std::endl;
}

我在Linux上同时使用g++和clang++(与libc++一起)。没有人能保证你的环境,但我敢打赌,最新的VS也应该工作。在Windows/VS平台上,char32_t可能是也可能不是比wchar_t更好的选择。VS并不完全符合标准,它的wchar_t不能代表扩展字符集的所有元素。它基本上是一个UTF-16码点。因此,如果在BMP之外有标点符号,则wchar_t正则表达式可能会失败。char32_t regexp不能在linux编译器/库中工作;YMMV .

如果你想直接操作utf -8编码的字节字符串,我猜你用标准c++库是不走运的。您需要第三方正则表达式库,例如PCRE。或者,动态地转换utf -8编码的字符串:

#include <regex>
#include <string>
#include <iostream>
#include <locale>
#include <codecvt>
int main ()
{
    std::locale::global(std::locale("en_US.utf8"));
    std::string str ="Hello'"#%&!.:,?¿World";
    std::regex re("[[:punct:]]", std::regex::extended ); // ¡No trabajo!
    str = std::regex_replace(str, re, " ");
    std::cout << str << std::endl;
    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> wconv;
    std::wstring wstr =  wconv.from_bytes(str);
    std::basic_regex<wchar_t> wre(L"[[:punct:]]", std::regex::extended );
    wstr = std::regex_replace(wstr, wre, L" ");
    str = wconv.to_bytes(wstr);
    std::cout << str << std::endl;
}