在 Embarcadero 的 C++ Builder 中使用 RegEx 将文本拆分为单个单词
Posted
技术标签:
【中文标题】在 Embarcadero 的 C++ Builder 中使用 RegEx 将文本拆分为单个单词【英文标题】:Using RegEx to split up a text into single words in Embarcadero's C++ Builder 【发布时间】:2016-08-30 10:14:18 【问题描述】:我正在使用 Embarcadero 的 C++ Builder 开发一个拼写检查应用程序。我使用正则表达式将文本拆分为单个单词。下面的代码在 RAD Studio XE 中运行良好,但与 RAD Studio Seattle 的行为方式不同。
当单词包含非拉丁字符(例如德语变音符号(Ä、Ö、Ü)或带有重音符号(é、ê、à)的字符时,就会出现问题。 "\w" 被解释为 [a-zA-Z_0-9] 忽略非拉丁字符。
首先,我的上下文中的单词是什么? 可能的词包括:
“\r\n”
“词-词-词-词...”
“单词。”或“单词-”
带撇号的单词:" 'word" "wor'd" "word' "
“单词”
有两种不同类型的撇号:' 和 '
这是代码:
String text (L"Österreich l'année);
const String sRegex (L"\r\n|(\\w+\\-)+\\w+|\\w+(\\.|\\-)|('|’)?\\w+('|’)?\\w*");
TRegEx regex(sRegex, TRegExOptions());
TMatchCollection regexMatches = regex.Matches(text);
for (int i=0; i<regexMatches.Count; ++i)
TMatch regexMatch = regexMatches.Item[i];
String word (regexMatch.Value);
//do stuff with word
字符串单词的期望值为“Österreich”和“l'année”。但是,RegEx 匹配的是“sterreich”、“l'ann”和“e”。
我的问题是,如何指定所有非拉丁字符?
【问题讨论】:
不知道你的风格是否支持它,但也许你可以在[\pL']*
工作。 See it here at regex101.
做个小测试:如果你的正则表达式风格是 PCRE,请在模式开头添加(*UTF)(*UCP)
。如果这不起作用,您可能正在处理不支持 Unicode 的 JS ECMAScript 5 正则表达式风格。
谢谢,使用 \pL 而不是 \w 有效!
@AndreasS.: \pL
只匹配字母。您的正则表达式包含\w
。让您的正则表达式模式识别 Unicode 更为合理。你试过L"(*UTF)(*UCP)\r\n|(\\w+\\-)+\\w+|\\w+(\\.|\\-)|('|’)?\\w+('|’)?\\w*"
吗?或者更好的一个 - L"(*UTF)(*UCP)\r\n|(\\w+-)+\\w+|\\w+[.-]|['’]?\\w+['’]?\\w*"
?
Hm, (*UTF) 和 (*UCP) 都会产生一个RegularExpressionError 异常,说'(*VERB) notrecognized'
【参考方案1】:
\pL
匹配 unicode 字母。尝试使用它而不是 \w
。
See it here at regex101.
如果您也需要数字(如\w
),请将\d
添加到组中。
【讨论】:
并避免使用 cmets ;) - unicode letter 我的意思是字母类别中的 unicode 代码点。 unicode letter 简化了答案(imo)。 只是添加:\pL
只匹配一个基本字母,如果也需要匹配变音符号,添加\pM
- [\pL\pM]
。还可以添加一个数字类(因为原来的 \w
包含数字)。以上是关于在 Embarcadero 的 C++ Builder 中使用 RegEx 将文本拆分为单个单词的主要内容,如果未能解决你的问题,请参考以下文章
Embarcadero C++ builder 10.4.2-附加到进程在 64 位上不起作用