如何正确处理单引号和双引号的转义
我有一个 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 个回答
这个解决方案适用于你在使用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})
这里有更多的选择,特别是 """
和 '''
可能正是你需要的。
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."""
根据我们在维基百科和W3学校上看到的信息,在节点内容中不应该出现'
和"
,虽然只有<
和&
被认为是严格禁止的。它们应该被相应的“预定义实体引用”替代,也就是'
和"
。
顺便说一下,我使用的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能够正确地处理转义字符。你能把你得到的错误信息(如果有的话)复制粘贴过来吗?