解析未知长度的 Unicode 名称

Parsing Unknown Length Unicode Name

这个问题我已经思考了一段时间,但似乎找不到解决方案。

我正在使用 pyparsing 来解析包含事件摘要的文本文件。每个文本文件都包含许多事件。每个事件,在几行 header 信息之后,以以下格式列出多个人和有关他们的数据:

word整数:用户名(整数word word word)

  1. 单词是静态的,永远一样
  2. 整数是任意整数
  3. 用户名可以是任何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 练习:将结果名称添加到整数和用户名中,以便更轻松地访问已解析的字段。