如何有效地解析包含大多数 unicode 字符的单词?
How to efficiently parse a word that includes the majority of unicode characters?
我在 Python 3.7 和 pyparsing==2.4.2
我基本上想以一种有效的方式解析以下内容:
import pyparsing as pp
content = pp.OneOrMore(
pp.Word(pp.pyparsing_unicode.printables, excludeChars="#<>;")
)
上面比
慢100倍左右
content = pp.OneOrMore(
pp.Word(pp.printables, excludeChars="#<>;")
)
使用 pp.CharsNotIn
再次相当快,但其行为方式与 pp.Word
有所不同。如果我在不匹配的字符中包含空格(这样我得到单独的标记),它就不能很好地与 pp.OneOrMore
.
结合
content = pp.OneOrMore(
pp.CharsNotIn(" \t\r\n#<>;")
)
解析时会导致ParseException
,例如
parser.content.parseString("foo bar", parseAll=True)
pyparsing.ParseException: Expected end of text, found 'b' (at char 4), (line:1, col:5)
这种情况有什么好的策略吗?
我想确保您的性能测试将创建表达式的时间和使用它进行解析的时间分开。 (我还尝试了另外两种正则表达式格式,如下所述。):
Create Word expression 6.56244158744812
Create Regex expression 0.0
Create Regex2 expression 3.991360902786255
Create Regex3 expression 0.4946744441986084
Parsing using Word expression
3.837733268737793
['foo', 'bar', '中文']
Parsing using Regex expression "[^ <>#;]+"
0.07877945899963379
['foo', 'bar', '中文']
Parsing using Regex2 expression "[pp.pyparsing_unicode.printables]+"
3.8447225093841553
['foo', 'bar', '中文']
Parsing using Regex3 expression "[pp.pyparsing_unicode.printables converted to ranges]+"
0.07676076889038086
['foo', 'bar', '中文']
您可以看到两者都正确解析了测试字符串,但 Regex 快了大约 40 倍。我还使用从创建的正则表达式进行了测试
"[" + pp.pyparsing_unicode.printables + "]+"
这最终与 Word 表达式大致相同。
最后,我使用通过将 pp.pyparsing_unicode.printables
转换为实际重新范围而不仅仅是一个而创建的正则表达式进行了测试
大百万字符的重新范围(例如将字母数字的正则表达式从
“[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]+”
到“[A-Za-z0-9]+”)。
这最终与否定范围匹配相当,让我相信将字符列表转换为重新范围
是一般解析单词的潜在加速(在解析器创建时有一个小的惩罚)。
我在 Python 3.7 和 pyparsing==2.4.2
我基本上想以一种有效的方式解析以下内容:
import pyparsing as pp
content = pp.OneOrMore(
pp.Word(pp.pyparsing_unicode.printables, excludeChars="#<>;")
)
上面比
慢100倍左右content = pp.OneOrMore(
pp.Word(pp.printables, excludeChars="#<>;")
)
使用 pp.CharsNotIn
再次相当快,但其行为方式与 pp.Word
有所不同。如果我在不匹配的字符中包含空格(这样我得到单独的标记),它就不能很好地与 pp.OneOrMore
.
content = pp.OneOrMore(
pp.CharsNotIn(" \t\r\n#<>;")
)
解析时会导致ParseException
,例如
parser.content.parseString("foo bar", parseAll=True)
pyparsing.ParseException: Expected end of text, found 'b' (at char 4), (line:1, col:5)
这种情况有什么好的策略吗?
我想确保您的性能测试将创建表达式的时间和使用它进行解析的时间分开。 (我还尝试了另外两种正则表达式格式,如下所述。):
Create Word expression 6.56244158744812
Create Regex expression 0.0
Create Regex2 expression 3.991360902786255
Create Regex3 expression 0.4946744441986084
Parsing using Word expression
3.837733268737793
['foo', 'bar', '中文']
Parsing using Regex expression "[^ <>#;]+"
0.07877945899963379
['foo', 'bar', '中文']
Parsing using Regex2 expression "[pp.pyparsing_unicode.printables]+"
3.8447225093841553
['foo', 'bar', '中文']
Parsing using Regex3 expression "[pp.pyparsing_unicode.printables converted to ranges]+"
0.07676076889038086
['foo', 'bar', '中文']
您可以看到两者都正确解析了测试字符串,但 Regex 快了大约 40 倍。我还使用从创建的正则表达式进行了测试
"[" + pp.pyparsing_unicode.printables + "]+"
这最终与 Word 表达式大致相同。
最后,我使用通过将 pp.pyparsing_unicode.printables
转换为实际重新范围而不仅仅是一个而创建的正则表达式进行了测试
大百万字符的重新范围(例如将字母数字的正则表达式从
“[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]+”
到“[A-Za-z0-9]+”)。
这最终与否定范围匹配相当,让我相信将字符列表转换为重新范围 是一般解析单词的潜在加速(在解析器创建时有一个小的惩罚)。