如何正确处理单引号和双引号的转义

6 投票
3 回答
5271 浏览
提问于 2025-04-17 04:31

我有一个 lxml 的 etree HTMLParser 对象,我想用它来构建 xpath,以便验证 xpath、xpath 的属性和标签的文本。但是,当标签的文本中包含单引号(')或双引号(")时,我遇到了问题,感觉所有的方法都试过了。

这是我创建的一个示例对象:

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

下面是代码片段,以及不同的变量读取方式:

   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 变量中的单引号和双引号呢?我尝试过三重引号、用 repr() 包裹 self.text,或者使用 re.sub 或 string.replace 来把 ' 和 " 转换成 \' 和 \"。

3 个回答

1

这个解决方案适用于你在使用Python的lxml库时。最好让lxml来处理转义问题。我们可以通过使用lxml的变量来做到这一点。

假设我们有下面的xpath

//tagname[text='some_text']`

如果some_text里面同时有单引号和双引号,就会导致"无效的谓词错误"。我试过的转义方法和三重引号都不管用,因为XML不接受三重引号。

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

我们将xpath转换成下面的样子:

//tagname[text = $var]

然后执行

find = etree.XPath(xpath)

接着将这些变量的值进行评估

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

这里有更多的选择,特别是 """''' 可能正是你需要的。

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."""
1

根据我们在维基百科W3学校上看到的信息,在节点内容中不应该出现'",虽然只有<&被认为是严格禁止的。它们应该被相应的“预定义实体引用”替代,也就是&apos;&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能够正确地处理转义字符。你能把你得到的错误信息(如果有的话)复制粘贴过来吗?

撰写回答