C/C++ PCRE 是否可以匹配 2 个或多个 UTF-8 代码点,这些代码点在 UTF-8 字符串中彼此相距甚远
Is it possible for C/C++ PCRE to match 2 or more UTF-8 codepoints which are far apart from each other in a UTF-8 String?
下午好,我们在WINDOWS Visual Studio 8.0和9.0上使用最新的C/C++版本的PCRE,具有PCRE_CASELESS,PCRE_UTF8,PCRE_UCP。当我们使用 PCRE 正则表达式 [\x{00E4}] 时{1}我们能够将标准拉丁语码位 U+00E4 与字符串 DAS tausendschã¶ne Jungfräulein(也称为 44 41 53 20 74 61 75 73 65 6E 64 73 63 68 C3 B6 6E 65 20 4A 75 6E 67 66 72 C3 A4 75 6C 65 69 6E。 现在我们想匹配代码点 U+00E4(即 C3 B6)和 U+00F6(即 C3 A4),这样我们就可以实现一个简单的原型 C/C++ 搜索和替换操作 $1 $2。这可能做到吗?谢谢。
我们现在使用具有以下C++函数的 PCRE 正则表达式[x{00F6}x{00E4}]{1,}
:
void cInternational::RegExSearchReplace(cOrderedList *RegExList_,char **Input_) {
const char *replacement;
char substitution[dMaxRegExSubstitution];
int subString;
cPCRE *regEx;
unsigned char* Buffer;
Buffer = new unsigned char[1024];
if (*Input_[0]!='x0' && RegExList_->ResetIterator()) {
do {
regEx=new cPCRE();
regEx->SetOptions(PCRE_CASELESS);
if (regEx->Compile(RegExList_->GetCharacterField(1))) {
// Search for Search RegEx:
while (regEx->Execute((char *)Buffer)>0) {
// Found it, get Replacement expression:
replacement=RegExList_->GetCharacterField(2);
int subLen=0;
// Build substitution string by finding each $# in replacement and replacing
// them with the appropriate found substring. Other characters in replacment
// are sent through, untouched.
for (int i=0;replacement[i]!='x0';i++) {
if (replacement[i]=='$' && isdigit(replacement[i+1])) {
subString=atoi(replacement+i+1);
if (regEx->HasSubString(subString)) {
strncpy(substitution+subLen,
*Input_+regEx->GetMatchStart(),
regEx->GetMatchEnd() - regEx->GetMatchStart());
subLen+=(regEx->GetMatchEnd() - regEx->GetMatchStart()
}
i++
} else {
substitution[subLen++]=replacement[i];
}
}
substitution[subLen]='x0';
// Adjust the size of Input_ accordingly:
int sizeDiff=strlen(substitution)-(regEx->GetMatchEnd()-regEx->GetMatchStart());
if (sizeDiff>0) {
char *newInput=new char[strlen(*Input_)+sizeDiff+1];
strcpy(newInput,*Input_);
delete[] *Input_;
*Input_=newInput;
}
memmove(*Input_ + regEx->GetMatchStart() + 1,
*Input_+regEx->GetMatchEnd() + 1,
regEx->GetMatchEnd()- regEx->GetMatchStart());
strncpy(*Input_,substitution,strlen(substitution));
(*Input_)[strlen(substitution)] = 'x0';
Buffer = Buffer + regEx->GetMatchEnd();
}
}
delete regEx;
} while (RegExList_->Next());
}
}
使用 PCRE,您用来匹配字符串中任何位置出现的正则表达式如下: x{00E4}.*x{00F6}
解释:
x{00E4}
匹配您要查找的第一个 Unicode 字符。
.
匹配任何字符。
*
修改前一个期间以匹配 0 次或更多次。这将允许第二个 unicode 字符是任意数量的字符。
x{00F6}
匹配您要查找的第二个 Unicode 字符。
如果它们出现,这将匹配。让我知道它是如何工作的,如果您需要它来做其他事情,等等(例如:这对于搜索和替换操作似乎不是那么有用。它只是会告诉你这些字符是否存在于字符串中。您需要修改正则表达式才能进行替换。
昨晚我给PCRE的开发人员Phip Hazel发了一封电子邮件。 Hazel 先生认为,可以实现对顺序不敏感的 PCRE 正则表达式,例如\x{00f6}.?\x{00e4} | \x{00e4}。?\x{00f6}
说明如下所示。谢谢你的帮助,达蒙。问候,弗兰克
寄件人:菲利普·黑兹尔日期: 2012年6月26日 星期二 at 8:55 上午致:张旭东抄送:pcre-dev@exim.org
2012年6月25日星期一,Frank Chang写道:
晚上好,我们正在使用 C/C++ PCRE 8.30 和 PCRE_UTF8 |PCRE_UCP | PCRE_COLLATE。这是一个不区分顺序的
正则表达式:"(?=.\x{00F6})(?=.\x{00E4})' 它尝试使用 ?= 或正数 向前看,确保两个 UTF-8 码位按任一顺序匹配。
PCRE_compile() 返回 OK,PCRE_execute() 返回字符串 DAS 上的 OK tausendschã¶ne Jungfrã¤ulein .十六进制为 44 41 53 20 74 61 75 73 65 6E 64 73 63 68 C3 B6 6E 65 20 4A 75 6E 67 66 72 C3 A4 75 6C 65 69 6E. 但是,GetMatchStart() 返回 0,GetMatchEnd() 返回 0 而不是 GetMatchStart() = 14 和 GetMatchEnd() = 27,我们在以下情况下获得 我们使用 PCRE '\x{00F6}.*\x{00E4}' 正则表达式。 请告知我们是否可以进行订单不敏感匹配 PCRE 正则表达式中的多个 UTF-8 代码点。谢谢。
我已经通过基本的pcretest程序运行了您的正则表达式,并且它匹配。这证实了您使用 PCRE_compile() 的发现和PCRE_execute()。
由于您的正则表达式完全由断言组成,因此实际匹配的字符串为空(如 PCRETEST 所示)。您需要将正则表达式修改为实际上匹配一些东西,如果你想给出一个匹配的开始和结束给你。如果你想要的是这两个代码点之间的字符串,在要么顺序,简单的东西,比如
\x{00f6}.?\x{00e4} | \x{00e4}。?\x{00f6}
(忽略空格)应该做你想做的事。
我意识到这个例子可能是你真实的简化应用程序,我的简单建议不能很好地扩展。但是要点:如果你想提取字符串,你的正则表达式必须做一些实际的匹配,而不仅仅是断言。
菲利普
--菲利普·黑兹尔
我们编写了一个 PCRE 顺序不敏感的正则表达式。
(?=.+(x{00F6})){1}(?=.+(x{00E4})){1}
这似乎功能正常。
- HEX值到wchar_t字符(UTF-8)的转换
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 从/到 UTF-8/UTF-16 的转换需要(例如:utf8 -> 代码点,然后代码点到 utf16)或(例如:utf8 -> utf16)?
- 如何将代码点转换为 utf-8
- 如何从 UTF-8 字符串的每个字符中获取 UNICODE 代码
- 如何在c++中将unicode代码点转换为utf-8
- 如何使Windows 7支持12000(UTF-32)代码页或1200(UTF-16)代码页
- 是否可以构造与 3 个或更多非连续 UTF 代码点匹配的 PCRE UTF-8 正则表达式
- C/C++ PCRE 是否可以匹配 2 个或多个 UTF-8 代码点,这些代码点在 UTF-8 字符串中彼此相距甚远
- 在编译/运行时将字符串文本的原始字节流入/流出Windows(非宽)执行字符集,以及ANSI代码页与UTF-8
- 如何以与字节序无关的方式读取 UTF-16 代码点的长度
- 如何遍历字符串中的所有utf-8代码点
- 如何在没有UTF-8特定代码的情况下解析多语言文档
- 是什么保证了存储在char32_t或char16_t-to-char中的UTF-8代码单元的static_cast将按预
- 为什么使用中文代码页集的Windows控制台可以显示UTF-16编码的字符