【问题标题】:How to properly escape single and double quotes如何正确转义单引号和双引号
【发布时间】:2011-10-18 04:28:42
【问题描述】:

我有一个 lxml etree HTMLParser 对象,我试图用它来构建 xpaths 来断言 xpaths、xpath 的属性和该标记的文本。当标签的文本有单引号(')或双引号(“)并且我已经用尽了所有选项时,我遇到了问题。

这是我创建的示例对象

parser = etree.HTMLParser()
tree = etree.parse(StringIO(<html><body><p align="center">Here is my 'test' "string"</p></body></html>), parser)

这是代码的 sn-p,然后是正在读入的变量的不同变体

   def getXpath(self)
     xpath += 'starts-with(., \'' + self.text + '\') and '
     xpath += ('count(@*)=' + str(attrsCount) if self.exactMatch else "1=1") + ']'

self.text 基本上是标签的预期文本,在这种情况下:Here is my 'test' "string"

当我尝试使用 HTMLParser 对象的 xpath 方法时失败

tree.xpath(self.getXpath())

原因是因为它得到的xpath是这个'/html/body/p[starts-with(.,'Here is my 'test' "string"') and 1=1]'

如何正确转义 self.text 变量中的单引号和双引号?我尝试过三重引用,将 self.text 包装在 repr() 中,或者做一个 re.sub 或 string.replace 转义 ' 和 " 与 \' 和 \"

【问题讨论】:

    标签: python lxml


    【解决方案1】:

    根据我们可以看到的in Wikipediaw3 school,您不应该在节点内容中包含'",即使只有&lt;&amp; 被认为是严格非法的。它们应替换为相应的“预定义实体引用”,即&amp;apos;&amp;quot;

    顺便说一句,我使用的 Python 解析器会透明地处理这个问题:在编写时,它们会被替换;阅读时,它们会被转换。

    在第二次阅读您的答案后,我在 Python 解释器中使用 ' 等测试了一些东西。它会为你逃脱一切!

    >>> 'text {0}'.format('blabla "some" bla')
    'text blabla "some" bla'
    >>> 'ntsnts {0}'.format("ontsi'tns")
    "ntsnts ontsi'tns"
    >>> 'ntsnts {0}'.format("ontsi'tn' \"ntsis")
    'ntsnts ontsi\'tn\' "ntsis'
    

    所以我们可以看到 Python 正确地转义了东西。然后您能否复制粘贴您收到的错误消息(如果有)?

    【讨论】:

    • 我明白了,我得到的错误来自 lxml: XPathEvalError: Invalid expression, stack trace is File "lxml.etree.pyx", line 2029, in lxml.etree._ElementTree.xpath ( src/lxml/lxml.etree.c:45934) 文件“xpath.pxi”,第 379 行,在 lxml.etree.XPathDocumentEvaluator.__call__ (src/lxml/lxml.etree.c:114389) 文件“xpath.pxi”,第 242 行,在 lxml.etree._XPathEvaluatorBase._handle_result (src/lxml/lxml.etree.c:113063) 文件“xpath.pxi”,第 228 行,在 lxml.etree._XPathEvaluatorBase._raise_eval_error (src/lxml/lxml.etree .c:112935)
    • mmh,lxml 引发错误,因为据说表达式无效。当print渲染时,您能否粘贴xpath的值?
    • 用相应的 HTML 实体转义 ' 和 " 就成功了。昨晚我真的很累,没想到字符串实际上是被解析的 HTML。感谢您提供此指导
    • 太好了,我就是这么想的:lxml 在内容中直接使用这些字符时并不高兴。不客气 - 请不要忘记接受答案!
    • 问题是我不得不放弃这个,因为它引起了很多头痛。后来我遇到了一个问题,即带下划线的 href 无法返回有效的 xpath,但只有在编写单元测试时,它在 python shell 本身中运行良好。此外,我正在处理可怕的 HTML,我还在 alt 属性中发现了无效字符。因此,经过一些试验和错误,我的工作正常,但我删除了 xpath 的开头部分并分别断言标签的文本
    【解决方案2】:

    有更多选项可供选择,尤其是 """''' 可能是您想要的。

    s = "a string with a single ' quote"
    s = 'a string with a double " quote'
    s = """a string with a single ' and a double " quote"""
    s = '''another string with those " quotes '.'''
    s = r"raw strings let \ be \"
    s = r'''and can be added \ to " any ' of """ those things'''
    s = """The three-quote-forms
           may contain
           newlines."""
    

    【讨论】:

      【解决方案3】:

      如果您使用 python lxml,则该解决方案适用。 最好将转义符留给lxml。我们可以通过使用lxmlvariables 来做到这一点。 假设我们有xpath 如下:

      //tagname[text='some_text']`
      

      如果some_text 有单引号和双引号,那么它会导致"Invalid Predicate error"。 对我来说既不是逃避工作,也不是三引号。因为 xml 不接受三引号。

      对我有用的解决方案是 lxml 变量。

      我们将xpath转换如下:

      //tagname[text = $var]
      

      然后执行

      find = etree.XPath(xpath)
      

      然后评估这些变量的值

      elements = find(root, {'var': text})
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-13
        • 2013-06-30
        • 1970-01-01
        • 2011-01-26
        • 2017-01-08
        • 2013-08-09
        • 1970-01-01
        相关资源
        最近更新 更多