使用 OpenXML 和 Regex 在 Word Docx 中查找和替换撇号 ( ' ) 的问题

Issue with find and replace apostrophe( ' ) in a Word Docx using OpenXML and Regex

Word 似乎使用了与 Visual Studio 不同的撇号字符,这会导致使用 Regex 时出现问题。

我正在尝试使用 OpenXML 在 C# 中编辑一些 Word 文档。我基本上用公司名称替换​​ [[COMPANY]]。在我遇到名称以 s 结尾的公司的极端情况之前,这一直很顺利。我最终遇到了问题 s,有时它会创建一个 s。

示例: 公司名称:Simmons Doc 中的文本:[[COMPANY]] 的业务是汽车。 结果:席梦思的生意是汽车。

这是不恰当的英语。

我应该可以像在 [[COMPANY]] 中那样使用基本的查找和替换,但它不起作用。

            Regex apostropheReplace = new Regex("s\'s");
            docText = apostropheReplace.Replace(docText, "s\'"); 

这不是。 Word 使用的字符 for 和 apostrophe(') 似乎与我在 Visual Studio 中使用键盘上的键时创建的标准字符不同。如果我使用我的键盘编写查找和替换,它将不起作用,但如果我从 Word 中复制并粘贴撇号,它就会起作用。

            Regex apostrophyReplace = new Regex("s\’s");
            docText = apostrophyReplace.Replace(docText, "s\'"); 

请注意第二个正则表达式中的不同字符。我对为什么会这样感到困惑,并且还想知道这是否是一种正确的方法。我试过“'”但那不起作用。我只想知道使用从 Word 中复制的字符是否是执行此操作的正确方法,是否有办法让两个字符都起作用,所以我对可能使用不同的文档创建的文档没有问题程序。

之所以会这样,是因为他们是不同的角色。

Word 实际上会在您键入某些标点符号后对其进行更改,以便为它们提供正确的倾斜度或改进演示文稿。

我 运行 之前在同一期中,我将其用作正则表达式:[\u2018\u2019\u201A\u201b\u2032']

所以基本上将您的代码修改为:

Regex apostropheReplace = new Regex("s\[\u2018\u2019\u201A\u201b\u2032']s");
docText = apostropheReplace.Replace(docText, "s\'")

我发现这是五种最常用的单引号和撇号类型。

如果您遇到与双引号相同的问题,您可以使用以下内容:[\u201C\u201D\u201E\u201F\u2033\u2036\"]

回答问题:

Is there a way to do it so that both characters work?

如果您希望一个正则表达式能够处理这两种情况,这可能是一个简单易读的解决方案:

 Regex apostropheReplace = new Regex("s\['’]s");
 docText = apostropheReplace.Replace(docText, "s\'")

这有一个额外的好处,那就是其他开发人员可以理解您试图涵盖两种撇号的情况。此好处涉及您问题的另一部分:

If using the copied character from Word is the proper way of doing this?

这取决于您所说的 "proper" 是什么意思。如果你的意思是 "most understandable to other developers," 我会说是的,因为需要最少的查找才能确切地知道你的正则表达式在寻找什么。如果您的意思是 "most performant",那么对于这种简单的 Regex 搜索来说应该不是问题(可以找到一些不错的 Regex 性能提示 here)。

如果您的意思是 "most versatile/robust single quote Regex",那么正如 @Leonardo-Seccia 指出的那样,还有其他字符编码可能会导致问题。 (列出了一些常见的 Microsoft Word here。)这样的解决方案可能如下所示:

Regex apostropheReplace =
    new Regex("s\['\u2018\u2019\u201A\u201b]s");
docText = apostropheReplace.Replace(docText, "s\'")

但您当然可以根据需要添加其他字符编码。可以找到更完整的字符编码列表 here - 要将它们添加到上面的正则表达式中,只需将 "U+" 更改为 "u" 并将其添加到列表中另一个“\”字符之后.例如,要将 "prime" 符号(′ 或 U+2032)添加到上面的列表中,请将 RegEx 字符串从

Regex("s\['\u2018\u2019\u201A\u201b]s")

Regex("s\['\u2018\u2019\u201A\u201b\u2032]s")

最终,您将根据您的用例来判断哪些字符编码最 "proper" 可以包含在您的 Regex 中。