【问题标题】:Replacing punctuation except intra-word dashes with a space用空格替换除单词内破折号以外的标点符号
【发布时间】:2016-06-07 10:35:57
【问题描述】:

R gsub("[^[:alnum:]['-]", " ", my_string) 中已经有一个接近的 answer,但它在 Python 中不起作用:

my_string = 'compactified on a calabi-yau threefold @ ,.'
re.sub("[^[:alnum:]['-]", " ", my_string)

'compactified on a calab yau threefold @ ,.'

因此,它不仅删除了单词内破折号,还删除了破折号之前单词的最后一个字母。而且它不会删除标点符号

预期结果(没有任何标点符号但字内破折号的字符串):'compactified on a calabi-yau threefold'

【问题讨论】:

  • [:alnum:] 匹配字母数字字符串。为什么不在 Python 中直接使用 r'[^\w['-]'
  • 我不知道我完全不懂正则表达式
  • 你需要更具体地说明你想做什么。
  • 为什么一件事在 R 中有效,但在 Python 中无效 - 无论如何,让我试试你的提议
  • @Alex 我怎么能比我的问题标题更明确?

标签: python regex r


【解决方案1】:

R 使用 TRE (POSIX) 或 PCRE 正则表达式引擎,具体取决于 perl 选项(或使用的函数)。 Python 使用经过修改的、更差的类似 Perl 的版本作为 re 库。 Python 不支持 POSIX 字符类,因为 [:alnum:] 匹配 alpha(字母)和 num(数字)。

在 Python 中,[:alnum:] 可以替换为 [^\W_](或仅 ASCII 的 [a-zA-Z0-9])和否定的 [^[:alnum:]] - 与 [\W_][^a-zA-Z0-9] 仅 ASCII 版本)。

[^[:alnum:]['-] 匹配 除字母数字(字母或数字)、['- 之外的任何 1 个符号这意味着您提到的 R 问题没有提供正确答案

您可以使用following solution

import re
p = re.compile(r"(\b[-']\b)|[\W_]")
test_str = "No -  d'Ante compactified on a calabi-yau threefold @ ,."
result = p.sub(lambda m: (m.group(1) if m.group(1) else " "), test_str)
print(result)

(\b[-']\b)|[\W_] regex 匹配并捕获字内 -',我们通过检查捕获组是否匹配并重新插入 m.group(1) 和其余部分(所有非-word 字符和下划线)只是用空格替换。

如果要删除包含一个空格的非单词字符序列,请使用

p = re.compile(r"(\b[-']\b)|[\W_]+") 

【讨论】:

  • 最后,检查了 POSIX 和 Python 正则表达式之间的否定 alnum 相关性。添加到答案中。请注意,\w/\W 版本适用于所有 Unicode 字母(如果您添加了 re.UNICODE 标志)。
  • 只有一件事:我注意到 '[ 没有被删除:请参阅 demo
  • 或许,你应该使用r"[\W_+['-]"(在我最终编辑之后,我没有更新最终模式)我现在将添加一个 Python 演示。
  • 实际上,独立的破折号被保留了——它们应该被删除,因为它们是标点符号(应该只保留单词内的破折号)
  • 您只对 ASCII 感兴趣吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 1970-01-01
  • 1970-01-01
  • 2013-07-08
  • 2016-01-08
  • 2012-12-25
相关资源
最近更新 更多