用正则表达式在Python中保留上下文的同时解析部分句子

2024-10-01 00:23:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我有许多json格式的课程,每个课程都有一个prerequisite字段,其中包含特定课程的先决条件列表,如下所示:

(为了简单起见,我们只需遵循aa111格式)

AAAA111, BBB111, CCC101, DDD104

每门课程都遵循\w{3,4}\d{3}的格式,因此在python中使用regex获得每一门课程并不太困难。你知道吗

问题:

我不知道是谁的天才认为这是一个聪明的方法,但没有一个一致的格式,在如何列出的先决条件列表。下面是我发现的一些列表的示例格式:

AAAA111, BBB111, CCC101, and DDD104
AAAA111, BBB111, CCC101 or DDD104
AAAA111, AAAA112 or AAAA113, BBB333
AAA111 or BBB111, AND CCC111
AAA111 or BBB111 or CCC111 or DDD111
AAA111 or 112 or 222 or 333
AAA111 or instructor permission
AAA111/221
and so on... :(

有成千上万的课程,我发现了如此多不同的形式,像这样,有时我想,如果只是更好地通过手每件事时,怪人的存在。你知道吗

因此,使用regex解析匹配到\w{3,4}\d{3}的特定过程并不难。使用regex来匹配关键字的存在,比如orandinstructor permission,也不是很难。你知道吗

我被困的地方是保留上下文。你知道吗

在上述示例中:

AAAA111, BBB111, CCC101, and DDD104

这样的先修课程表意味着这门课程需要全部4门课程。你知道吗

AAAA111, BBB111, CCC101 or DDD104
AAA111 or 112 or 222 or 333

这样的先修课程表意味着这门课程只需要4门中的1门或更多。你知道吗

AAAA111, AAAA112 or AAAA113, BBB333

但对于这样的怪人。。。你知道吗

我能做什么?显然,仅仅有一个在orand或其他类似关键字出现时被激活的标志是行不通的。我被困在如何在维护上下文的同时最好地解析它。一个人读了这篇文章就很容易理解它的来龙去脉,但是。。。你知道吗

编辑:既然清晰似乎是一个问题,我会尽量在这里更清楚。 我想做的是改变每门课程的每门必修课列表,使它们都有一个一致的,程序可读的格式。你知道吗


Tags: orand示例列表先决条件格式regex课程
1条回答
网友
1楼 · 发布于 2024-10-01 00:23:25

您可以尝试使用^{},这是一个非常适合处理语法的库。你知道吗

如果条目具有一致的(布尔)逻辑,并且您知道如何解释andor之间的逗号,那么您可以尝试使用基于pyparsing中^{}示例的脚本来解析条目:

import pprint
import string

from pyparsing import Word, nums, Literal, opAssoc, operatorPrecedence


course_name = Word(string.ascii_uppercase + nums + "/") | Literal("instructor permission")
comma_separator = Literal(',')
comma_separator.setParseAction(lambda t:"&&")

and_separator = Literal(', and') | Literal(', AND') | Literal('and')  | Literal('AND')
and_separator.setParseAction(lambda t:"&&")

or_separator = Literal('or') | Literal("OR")
or_separator.setParseAction(lambda t:"||")

course_line = operatorPrecedence(course_name,
                            [
                                (and_separator, 2, opAssoc.LEFT,),
                                (or_separator, 2, opAssoc.LEFT),
                                (comma_separator, 2, opAssoc.LEFT,),
                            ])

data = """AAAA111, BBB111, CCC101, and DDD104
AAAA111, BBB111, CCC101 or DDD104
AAAA111, AAAA112 or AAAA113, BBB333
AAA111 or BBB111, AND CCC111
AAA111 or BBB111 or CCC111 or DDD111
AAA111 or 112 or 222 or 333
AAA111 or instructor permission
AAA111/221
"""

for line in data.splitlines():
    results = course_line.parseString(line)
    print(line)
    pprint.pprint(results.asList()[0])
    print()

打印:

AAAA111, BBB111, CCC101, and DDD104
['AAAA111', '&&', 'BBB111', '&&', ['CCC101', '&&', 'DDD104']]

AAAA111, BBB111, CCC101 or DDD104
['AAAA111', '&&', 'BBB111', '&&', ['CCC101', '||', 'DDD104']]

AAAA111, AAAA112 or AAAA113, BBB333
['AAAA111', '&&', ['AAAA112', '||', 'AAAA113'], '&&', 'BBB333']

AAA111 or BBB111, AND CCC111
['AAA111', '||', ['BBB111', '&&', 'CCC111']]

AAA111 or BBB111 or CCC111 or DDD111
['AAA111', '||', 'BBB111', '||', 'CCC111', '||', 'DDD111']

AAA111 or 112 or 222 or 333
['AAA111', '||', '112', '||', '222', '||', '333']

AAA111 or instructor permission
['AAA111', '||', 'instructor permission']

AAA111/221
'AAA111/221'

相关问题 更多 >