我有一个字符串可以包含这样的东西:
s = "'Mark, Bob','John'"
将其解析为 3 个字符串的最佳方法是什么?我对pyparsing真的很陌生,恐怕我不太了解它
(编辑)对不起,我不是很清楚。这是使用语法和 pyparsing 解析文件的程序的一部分。这是输入的一小部分,我不确定如何处理。这应该真正代表三个名称的数组,这就是我想摆脱的。
谢谢
我假设您实际上想要 2 个字符串,而不是 3 个(根据引号判断)。
要使用 pyparsing,您首先要考虑并写下要解析的格式(无论您将使用什么解析库或工具,这实际上都是一个很好的第一步)。它可以像你想要的那样严格,但是让我们从这个问题的简单/高级开始。我将使用准 BNF 形式,其中 '*' 表示“0 次或多次重复”:
list_of_names = quoted_string (',' quoted_string)*
“名称列表是一个带引号的字符串,后跟 0 个或多个逗号和带引号的字符串对。”
Pyparsing 的类使用的名称虽然对于编码来说可能有点冗长,但相当准确地遵循相同的形式。
list_of_names = quotedString + ZeroOrMore(',' + quotedString)
Pyparsing 还包括一些常用的表达式,quotedString 就是其中之一。
现在我们已经定义了list_of_names
,我们可以使用它来解析您的输入:
s = "'Mark, Bob','John'"
print list_of_names.parseString(s)
我们得到:
["'Mark, Bob'", ',', "'John'"]
嗯,这很丑。一方面,我们只需要名称,而不是任何分隔逗号。所以list_of_names
改为:
list_of_names = quotedString + ZeroOrMore(Suppress(',') + quotedString)
现在它被清理了一点:
["'Mark, Bob'", "'John'"]
您不清楚是否要保留引号。通常当我使用字符串时,我只想要字符串内容,而不是让字符串包含引号。你当然可以这样写:
for name in list_of_names.parseString(s):
print name.strip("'")
但是您可能想要对这个解析后的输出做很多事情,并且您不想每次做某事时都必须为剥离引号而烦恼。
因此,您可以定义一个解析操作,一个在解析时运行的回调,它将清理这些引号。Pyparsing 包括一个叫做removeQuotes
的,你把它包括在你的解析器中,如下所示:
quotedString.setParseAction(removeQuotes)
现在,如果我们再次解析您的输入,我们会得到一个非常干净的列表:
['Mark, Bob', 'John']
最后,这种解析表单列表的业务经常something + ZeroOrMore(Suppress(delimiter) + something)
发生,尤其是当分隔符是逗号时。所以 pyparsing 包含一个辅助方法delimitedList
,称为发出相同的东西。你的整个解析器现在看起来像:
quotedString.setParseAction(removeQuotes)
list_of_names = delimitedList(quotedString)
然后通过调用表达式的parseString
方法来提取数据。list_of_names
#!/usr/bin/python
from pyparsing import *
s = "'Mark, Bob','John'"
fnames = OneOrMore(Suppress(Literal("\'")) | Suppress(Literal("\"")) | Suppress(",") | Word(alphas))
for n in fnames.parseString(s):
print n
运行时只输出名称:
Mark
Bob
John