VSCode 中的正则表达式:捕获每个字符/字母 - 不仅仅是 ASCII

Posted

技术标签:

【中文标题】VSCode 中的正则表达式:捕获每个字符/字母 - 不仅仅是 ASCII【英文标题】:RegEx in VSCode: capture every character/letter - not just ASCII 【发布时间】:2022-01-21 15:54:09 【问题描述】:

我正在处理历史文本,我想用 RegEx 重新格式化它。问题是:文本中有很多特殊字符(即:字母)与 [a-z] / [A-Z] 或 \w 等 RegEx 字符类不匹配。 例如,我想匹配以下行中的点(并且只有点):

<tag1>Quomodo restituendus locus Demosth. Olÿnth</tag1>

没有 ÿ 我可以轻松使用上述字符类,例如:

(?<=(<tag1>(\w|\s)*))\.(?=((\w|\s)*</tag1>))

但它不适用于 ASCII 未涵盖的特殊字符。我尝试了很多东西,但我无法让它工作,所以 RegEx 真的只捕获了这一行中的点。如果我使用更通用的表达式,例如 (.)* (而不是 (\w|\s)* ),我会在文档中得到更多的点(例如,不在开始和结束标记之间但在之间的点两个这样的标签集),这不是我想要的。对于涵盖所有 unicode 字母的表达式有什么想法吗?

【问题讨论】:

你是说这个\. 不匹配点? 请注意,xml 正则表达式不合适。请注意,两者之间的内容并不重要,您不需要肯定的断言来确保点位于打开和关闭标签之间。我需要一半的时间来详细解释这一点。这与 Unicode 无关! 【参考方案1】:

使用排除点和左尖括号的否定字符类:

(?<=<tag1>[^.<]*(?:<(?!/tag1>)[^.<]*)*)\.

使用这种模式,甚至不需要检查结束标记。但是,如果您绝对想检查它,请以以下方式结束模式:

(?=[^<]*(?:<(?!/tag1>)[^<]*)*</tag1>)

【讨论】:

谢谢!这在一种情况下确实很完美:标签之间只有一个点。我知道,我没有指定这一点,但在我的情况下可以有几个点(实际上它们用于标记缩写,例如在名称中它可能看起来像这样:JR Ewing【参考方案2】:

您可以将&lt;&gt; 之间的任何文本与[^&lt;&gt;]* 匹配:

(?<=(<tag1>[^<>]*))\.(?=([^<>]*</tag1>))

请参阅regex demo。不确定你是否需要所有这些捕获组,没有它们你可能会得到你需要的东西:

(?<=<tag1>[^<>]*)\.(?=[^<>]*</tag1>)

见this regex demo。 详情

(?&lt;=&lt;tag1&gt;[^&lt;&gt;]*) - 紧跟在&lt;tag1 前面的位置,然后是除&lt;&gt; 之外的任何零个或多个字符 \. - 一个点 (?=[^&lt;&gt;]*&lt;/tag1&gt;) - 紧接在除&lt;&gt;&lt;/tag1&gt; 之外的任何零个或多个字符前面的位置。

【讨论】:

以上是关于VSCode 中的正则表达式:捕获每个字符/字母 - 不仅仅是 ASCII的主要内容,如果未能解决你的问题,请参考以下文章

用于捕获嵌套括号中的值的正则表达式

如何在正则表达式中使用带有字符的“环视”来捕获整个字符串?

量词可以用于R中的正则表达式替换吗?

.NET中具有重复字符和长度的正则表达式

正则表达式:匹配字母数字和空格,但前导空格除外

正则表达式捕获字符后的文本并以空格​​结尾[重复]