解析未知长度的 Unicode 名称
Parsing Unknown Length Unicode Name
这个问题我已经思考了一段时间,但似乎找不到解决方案。
我正在使用 pyparsing 来解析包含事件摘要的文本文件。每个文本文件都包含许多事件。每个事件,在几行 header 信息之后,以以下格式列出多个人和有关他们的数据:
word整数:用户名(整数word word word)
- 单词是静态的,永远一样
- 整数是任意整数
- 用户名可以是任何unicode字符,包括符号,也可以包括空格
我似乎无法构建可以处理所有这些可能性的语法。它在解析奇怪的 unicode 字符以及 whitespace/symbols 时卡住了。下面的示例 3 难倒了我。
示例:
你好 1: -fred,123(100 你好堆栈溢出)
你好 2:我叫布伦特(250 你好堆栈溢出)
你好 3:äää + óóó(0 你好堆栈溢出)
有人有什么建议吗?
编辑:
感谢您的回复。这很有效,但是当我转到文本文件的下一部分时,我 运行 又遇到了同样的问题。不确定我是应该开始一个新问题还是只添加这个问题。
我现在正在尝试解析以下各种行:
用户名:action-name action-details
用户名操作
示例:
brent morrow: add 10 to 20
brent:morrow: walks
äää + óóó: stands
brent morrow has returned
所有 action-name 和 action-details 都是静态和已知的。
所以我 运行 遇到了一个问题,我无法跳到用户名以外的文本,因为它可能是许多不同的操作之一。它最终只打印了整个文本文件(或至少是其中的重要部分)。
我完全被难住了。我基本上是在想办法展望未来,找到以下内容:
冒号+action-name+动作细节
或
空格 + 动作
... 然后取之前的所有字符(用户名)。但是 action-name/action-details/action 可以是预定义操作列表中的许多操作之一。否定前瞻,~,看起来很有希望,但我似乎无法找到接受用户名的所有 unicode 字符的解决方案。
正在解析的文本文件来自我无法控制的第三方,因此无法找到更具体地构建源文件的方法。
尝试使用 SkipTo
(代码使用最新的 pyparsing 2.1.4 运行测试功能):
# -*- coding: utf-8 -*-
tests = """
# a regular line
hello 1: -fred,123 (100 hello stack overflow)
# a username with spaces
hello 2: my name is brent (250 hello stack overflow)
# a username with non-ASCII
hello 3: äää + óóó (0 hello stack overflow)
"""
from pyparsing import *
COLON,LPAR,RPAR = map(Suppress, ":()")
integer = pyparsing_common.integer
leading = "hello" + integer + COLON
trailing = LPAR + integer + "hello" + "stack" + "overflow" + RPAR
strip = lambda t: t[0].strip()
line = leading + SkipTo(trailing).setParseAction(strip) + trailing
line.runTests(tests)
给出:
# a regular line
hello 1: -fred,123 (100 hello stack overflow)
['hello', 1, '-fred,123', 100, 'hello', 'stack', 'overflow']
# a username with spaces
hello 2: my name is brent (250 hello stack overflow)
['hello', 2, 'my name is brent', 250, 'hello', 'stack', 'overflow']
# a username with non-ASCII
hello 3: äää + óóó (0 hello stack overflow)
['hello', 3, '\xe4\xe4\xe4 + \xf3\xf3\xf3', 0, 'hello', 'stack', 'overflow']
OP 练习:将结果名称添加到整数和用户名中,以便更轻松地访问已解析的字段。
这个问题我已经思考了一段时间,但似乎找不到解决方案。
我正在使用 pyparsing 来解析包含事件摘要的文本文件。每个文本文件都包含许多事件。每个事件,在几行 header 信息之后,以以下格式列出多个人和有关他们的数据:
word整数:用户名(整数word word word)
- 单词是静态的,永远一样
- 整数是任意整数
- 用户名可以是任何unicode字符,包括符号,也可以包括空格
我似乎无法构建可以处理所有这些可能性的语法。它在解析奇怪的 unicode 字符以及 whitespace/symbols 时卡住了。下面的示例 3 难倒了我。
示例:
你好 1: -fred,123(100 你好堆栈溢出)
你好 2:我叫布伦特(250 你好堆栈溢出)
你好 3:äää + óóó(0 你好堆栈溢出)
有人有什么建议吗?
编辑:
感谢您的回复。这很有效,但是当我转到文本文件的下一部分时,我 运行 又遇到了同样的问题。不确定我是应该开始一个新问题还是只添加这个问题。
我现在正在尝试解析以下各种行:
用户名:action-name action-details 用户名操作
示例:
brent morrow: add 10 to 20
brent:morrow: walks
äää + óóó: stands
brent morrow has returned
所有 action-name 和 action-details 都是静态和已知的。
所以我 运行 遇到了一个问题,我无法跳到用户名以外的文本,因为它可能是许多不同的操作之一。它最终只打印了整个文本文件(或至少是其中的重要部分)。
我完全被难住了。我基本上是在想办法展望未来,找到以下内容:
冒号+action-name+动作细节
或
空格 + 动作
... 然后取之前的所有字符(用户名)。但是 action-name/action-details/action 可以是预定义操作列表中的许多操作之一。否定前瞻,~,看起来很有希望,但我似乎无法找到接受用户名的所有 unicode 字符的解决方案。
正在解析的文本文件来自我无法控制的第三方,因此无法找到更具体地构建源文件的方法。
尝试使用 SkipTo
(代码使用最新的 pyparsing 2.1.4 运行测试功能):
# -*- coding: utf-8 -*-
tests = """
# a regular line
hello 1: -fred,123 (100 hello stack overflow)
# a username with spaces
hello 2: my name is brent (250 hello stack overflow)
# a username with non-ASCII
hello 3: äää + óóó (0 hello stack overflow)
"""
from pyparsing import *
COLON,LPAR,RPAR = map(Suppress, ":()")
integer = pyparsing_common.integer
leading = "hello" + integer + COLON
trailing = LPAR + integer + "hello" + "stack" + "overflow" + RPAR
strip = lambda t: t[0].strip()
line = leading + SkipTo(trailing).setParseAction(strip) + trailing
line.runTests(tests)
给出:
# a regular line
hello 1: -fred,123 (100 hello stack overflow)
['hello', 1, '-fred,123', 100, 'hello', 'stack', 'overflow']
# a username with spaces
hello 2: my name is brent (250 hello stack overflow)
['hello', 2, 'my name is brent', 250, 'hello', 'stack', 'overflow']
# a username with non-ASCII
hello 3: äää + óóó (0 hello stack overflow)
['hello', 3, '\xe4\xe4\xe4 + \xf3\xf3\xf3', 0, 'hello', 'stack', 'overflow']
OP 练习:将结果名称添加到整数和用户名中,以便更轻松地访问已解析的字段。