首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从字符串中拆分数据并将其放入预定义的类别中?

如何从字符串中拆分数据并将其放入预定义的类别中?
EN

Stack Overflow用户
提问于 2020-03-25 08:35:53
回答 2查看 34关注 0票数 0

我正在尝试将存储在数组中的以下句子分成几类。这些类别是线号、车站、关闭类型和日期,因为我抓取的所有地铁关闭公告都是这种格式。

代码语言:javascript
运行
复制
"Line 1: Finch to Sheppard-Yonge nightly early closures March 23 to 26 - CANCELLED"
"Line 1: Lawrence to St Clair weekend closure Sunday, March 29 - REVISED"
"Line 1: Sheppard-Yonge to St Clair nightly early closures March 30 to April 2 - REVISED"9

例如:

代码语言:javascript
运行
复制
Line = {0:"Line 1", 1:"Line 1", 2:"Line 1"}
Stations = {0: "Finch to Sheppard-Yonge", 1:"Lawrence to St Clair", 2:"Sheppard-Yonge to St Clair"}

我已经创建了一些非常复杂的for循环来做这件事,然而,它们有相当多的buggy,并且对于每个类别需要不同的代码逻辑。下面是我如何从上面的句子中提取“闭包类型”的示例,我假设有3种闭包类型存储在closure_types数组中:

代码语言:javascript
运行
复制
closure_types = ["nightly early closures","single day closure","weekend closure"]
closure_types_split = []
for closure_type in closure_types:
    split_closure_type_a = closure_type.split()
    closure_types_split.append(split_closure_type_a)


closure_type_categorized = []
for i in range(len(split_closures)): 
    for ins in range(len(closure_types_split)):
        try:
            first_word_in_closure_types_split = closure_types_split[ins][0]
            first_word = split_closures[i].index(str(first_word_in_closure_types_split))
            if split_closures[i][first_word] == 'nightly':
                last_word = first_word + 3
                closure_type_categorized.append(split_closures[i][first_word:last_word])
            elif split_closures[i][first_word] == 'single':
                last_word = first_word + 2
                closure_type_categorized.append(split_closures[i][first_word:last_word])
            elif split_closures[i][first_word] == 'weekend':
                last_word = first_word + 2
                closure_type_categorized.append(split_closures[i][first_word:last_word])
        except:
            pass

我的问题是,有没有更简单的方法来做我想做的事情?或者有没有什么python库被设计用来做我想做的事情?

EN

回答 2

Stack Overflow用户

发布于 2020-03-26 04:45:24

这可以使用正则表达式来处理

代码语言:javascript
运行
复制
import re

# note: spaces in the names must use `\s` (see St Clair), 
# because the re pattern uses verbose mode.
stations = '|'.join(line.strip() for line in 
    r"""
    Finch
    Lawrence
    Sheppard-Yonge
    St\sClair
    """.strip().splitlines())

# The re pattern is a raw f-string so the {stations} can be inserted.
pattern = rf"""(?ix)
    Line\s+(?P<line>\d+):
    \s*
    (?P<where>(?:{stations})(?:\s*to\s*(?:{stations}))*)    # one or more stations separated by 'to'
    \s*
    (?P<what>(?:\w*\s+)*?closures?)                         # phrase ending with closure or closures
    \s*
    (?P<when>[^-]*)                                         # everything up to a '-'
    \s*
    (?:-\s* (?P<note>.*))?                                  # if there is a '-' everything after it
    """

template = re.compile(pattern)

在测试用例上使用它:

代码语言:javascript
运行
复制
testcases = [
    "Line 1: Finch to Sheppard-Yonge nightly early closures March 23 to 26 - CANCELLED",
    "Line 1: Lawrence to St Clair weekend closure Sunday, March 29 - REVISED",
    "Line 1: Sheppard-Yonge to St Clair nightly early closures March 30 to April 2 - REVISED",
]

for test in testcases:
    mo = template.search(test)
    print(mo.groupdict())

打印:

代码语言:javascript
运行
复制
{'line': '1', 'where': 'Finch to Sheppard-Yonge', 'what': 'nightly early closures', 'when': 'March 23 to 26 ', 'note': 'CANCELLED'}
{'line': '1', 'where': 'Lawrence to St Clair', 'what': 'weekend closure', 'when': 'Sunday, March 29 ', 'note': 'REVISED'}
{'line': '1', 'where': 'Sheppard-Yonge to St Clair', 'what': 'nightly early closures', 'when': 'March 30 to April 2 ', 'note': 'REVISED'}

对于更复杂的解析问题,我喜欢TatSu库。

票数 1
EN

Stack Overflow用户

发布于 2020-03-25 11:41:38

你的语法看起来很简单。例如:“1号线:芬奇至谢泼德-永吉夜间提前关闭3月23日至26日-取消”“1号线:劳伦斯至圣克莱尔周末关闭,3月29日星期日-修订”1号线:谢泼德至永吉至圣克莱尔3月30日至4月2日夜间提前关闭-修订

代码语言:javascript
运行
复制
NOTICE => LINE_FIELD STATIONS CLOSURE DATES "-" STATUS
LINE_FIELD => "Line " integer ":"
STATIONS => string {"to" string}
CLOSURE => string ["closure" | "closures"] string
DATES => DATE_1 {to DATE_2}
DATE_1 => month integer
DATE_2 => {month} integer
STATUS => ["CANCELLED" | "REVISED"]

我把语法交给你做了。在顶层的关键解析点是找到“闭合”字来提取闭合短语,并找到连字符来分隔最后的短语。

这能让你行动起来吗?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60841406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档