【问题标题】:Accommodate two types of quotes in a regex在正则表达式中容纳两种类型的引号
【发布时间】:2012-04-09 06:20:48
【问题描述】:

我正在使用正则表达式替换输入字符串中的引号。我的数据包含两种“类型”的引号 -

" and “

两者之间有一个非常微妙的区别。目前,我在我的正则表达式中明确提到了这两种类型

\"*\“*

我担心在未来的数据中我可能会得到一个不同的“类型”的引用,我的正则表达式可能会失败。存在多少种不同类型的报价?有没有办法将这些规范化为一种类型,这样我的正则表达式就不会因看不见的数据而中断?

编辑 -

我的输入数据由 HTML 文件组成,我将 HTML 实体和 URL 转义为 ASCII

escaped_line = HTMLParser.HTMLParser().unescape(urllib.unquote(line.decode('ascii','ignore')))

其中 line 指定 HTML 文件中的每一行。我需要“忽略”ASCII,因为我数据库中的所有文件都没有相同的编码,而且在读取文件之前我不知道编码。

编辑2

我无法使用替换功能这样做。我尝试了 replace('"','') 但它不能替换其他类型的引号 '"'。如果我将它添加到另一个替换函数中,它会抛出非 ASCII 字符错误。

条件

不允许使用外部库,只能使用本机 python 库。

【问题讨论】:

  • 替换引号几乎不是正则表达式的任务。我会得到一个(unicode?)引号列表并做一个普通的replace
  • @Lev Levitsky,unicode 究竟如何在这里工作?我无法使用替换功能这样做。我尝试了 replace('"','') 但它不能替换其他类型的引号 '“'。如果我将它添加到另一个替换函数中,它会抛出非 ASCII 字符错误。我是 unicode 的新手。
  • 看起来您对 urllib.unquote 的调用遇到了以下尚未解决的 Python 错误:bugs.python.org/issue8136
  • @Abel 在这种情况下我该怎么办?
  • @mcenley:您正在转义 HTML,就好像它是一个 URL。也许你根本不需要逃避。考虑将 HTML 读取为 UTF-8(它可能已经是,或者在源代码处修复它),这样您就不需要任何转义。

标签: python regex quotes double-quotes


【解决方案1】:

我只能帮助您解决有关引号的原始问题。事实证明,Unicode 为每个字符定义了许多属性,这些都可以通过 Unicode 字符数据库获得。 “引号”是这些属性之一。

存在多少种不同类型的引号?

29,根据 Unicode,见下文。

Unicode 标准为我们带来了一个关于 Unicode 属性的权威文本文件,PropList.txt,其中包含一个引号列表。由于 Python 没有support all Unicode properties in regular expressions,因此您目前不能使用\p{QuotationMark}。但是,创建一个正则表达式字符类很简单:

// placed on multiple lines for readability, remove spaces
// and then place in your regex in place of the current quotes
[\u0022   \u0027    \u00AB    \u00BB
\u2018    \u2019    \u201A    \u201B
\u201C    \u201D    \u201E    \u201F
\u2039    \u203A    \u300C    \u300D
\u300E    \u300F    \u301D    \u301E
\u301F    \uFE41    \uFE42    \uFE43
\uFE44    \uFF02    \uFF07    \uFF62
\uFF63]

正如上面“tchrist”所指出的,你可以使用支持\p{QuotationMark}Matthew Barnett's regex library来省去麻烦。

【讨论】:

  • 谢谢,但我不能使用任何外部库。我已经编辑了问题以指定这一点。
  • @mcenley:我明白了,所以选择另一个选项并使用字符类。只需复制并粘贴并删除空格(但也:解决您的编码问题,在此之前所有赌注都关闭;)。
  • 如何解决编码问题?这对我来说真的很重要,而不是我注册的。 :-(
【解决方案2】:

原来有一种更简单的方法可以做到这一点。只需在您用python编写的正则表达式前面附加文字'u'。

regexp = ru'\"*\“*'

当您想要编译/搜索/匹配您的正则表达式与您的字符串时,请确保使用 re.UNICODE 标志。

re.findall(regexp, string, re.UNICODE)

不要忘记包含

#!/usr/bin/python
# -*- coding:utf-8 -*-

在源文件的开头,以确保可以将 unicode 字符串写入源文件。

【讨论】:

  • 这回答了您的第二次编辑,而不是您最初的问题,“存在多少种不同类型的引号?有没有办法将它们标准化为一种类型,这样我的正则表达式就不会中断看不见的数据?” 没有回答这个问题。第一部分:根据 Unicode 的 29 种引号,第二部分:\p{QuotationMark}(但目前需要外部库)。
  • @Abel 很公平,但我现在可以将它添加到我想要的正则表达式(29 种类型)中。
【解决方案3】:

我认为 Python 的正则表达式实现中没有“引号”字符类,因此您必须自己进行匹配。

您可以保留常用引号 unicode 字符 (here's a list for a good start) 的列表,并以编程方式构建匹配引号的正则表达式部分。

【讨论】:

  • 很抱歉在这件事上打扰您,但它究竟是如何工作的呢?我在替换功能上遇到了非 ASCII 字符错误(检查已编辑的问题)。
  • 我会尝试几件事:确保您的编辑器保存编码为 utf-8 的文件,在源文件顶部添加 #coding: utf-8 注释,在之前添加“u”包含 unicode 引号字符的字符串,例如:u"»"。
  • 如果你使用 Matthew Barnett 的 regex Python 2 或 3 库,你可以使用 \p{qmark}
  • @tchrist 我很遗憾不能使用任何外部库。只需要使用本机 python 库来执行此操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
  • 2020-12-28
  • 2021-09-02
  • 1970-01-01
相关资源
最近更新 更多