微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 Python 的 parsec.py 库进行递归解析

如何解决使用 Python 的 parsec.py 库进行递归解析

我有一个关于使用 Python 的 parsec.py 库进行解析的基本问题。

我想在文本中的某处提取日期。例如,

Lorem ipsum dolor sit amet. A number 42 is present here. But here is a date 11/05/2017. Can you extract this?

Lorem ipsum dolor sit amet.
A number 42 is present here.

But here is a date 11/05/2017. Can you extract this?

在这两种情况下,我都希望解析器返回 11/05/2017

我只想使用 parsec.py 解析库,我不想使用正则表达式。 parsec 的内置正则表达式函数没问题。

我尝试过类似的东西

from parsec import *

ss = "Lorem ipsum dolor sit amet. A number 42 is present here. But here is a date 11/05/2017. Can you extract this?"

date_parser = regex(r'[0-9]{2}/[0-9]{2}/[0-9]{4}')

date = date_parser.parse(ss)

我得到 ParseError: expected [0-9]{2}/[0-9]{2}/[0-9]{4} at 0:0

有没有办法在达到 date_parser 模式之前忽略文本?没有错误

解决方法

你想要的是一个解析器,它跳过任何不匹配的字符,然后解析一个正则表达式。

日期模式可以用 $sql = "SELECT * FROM accounts LEFT OUTER JOIN rosters ON accounts.id=rosters.id WHERE stafffname<>'admin' ORDER BY rosters.week_start ASC,accounts.stafffname ASC"; $result = $mysqli->query($sql); if($result->num_rows > 0) { while($row = $result->fetch_assoc()) { $comments = str_replace('+','<br/>',$row['comments']); $comments = str_replace('{','<strong/>',$comments); $comments = str_replace('}','</strong/>',$comments); echo ' <tr class><!-- 2nd row STAFF MEMBER 5--> <td><!--Date Range--> '.$row["stafffname"].' '.$row["id"].' </td> <td><!--Date Range--> '.date("d M Y",strtotime($row["week_start"])).' </td> <td><!--Mon Time--> '.substr($row["mon_start"],5).' - '.substr($row["mon_end"],5).' </td> <td><!--Tue Time--> '.substr($row["tue_start"],5).' - '.substr($row["tue_end"],5).' </td> <td><!--Wed Time--> '.substr($row["wed_start"],5).' - '.substr($row["wed_end"],5).' </td> <td><!--Thu Time--> '.substr($row["thu_start"],5).' - '.substr($row["thu_end"],5).' </td> <td><!--Fri Time--> '.substr($row["fri_start"],5).' - '.substr($row["fri_end"],5).' </td> <td><!--Sat Time--> '.substr($row["sat_start"],5).' - '.substr($row["sat_end"],5).' </td> <td><!--Comments--> '.$comments.' </td> <td><!--Comments--> <a href="rcreate.php?id='.$row["id"].'&tabid=3" class="btn btn-danger btn-sm">Add</a> <a href="redit.php?id='.$row["id"].'&tabid=3&rosterID='.$row["rosterID"].'" class="btn btn-warning btn-sm">Edit</a> </td> </tr> '; } 解析器定义,

regex

我们首先定义一个解析器,它使用任意字符(将包含在库中(编辑:已包含在 v3.9 中)),

date_pattern = regex(r'[0-9]{2}/[0-9]{2}/[0-9]{4}')

为了表达“跳过任何字符并匹配模式”的想法,我们需要将递归解析器定义为

def any():
    '''Parse a random character.'''
    @Parser
    def any_parser(text,index=0):
        if index < len(text):
            return Value.success(index + 1,text[index])
        else:
            return Value.failure(index,'a random char')
    return any_parser

但它不是一个有效的python表达式,因此我们需要

date_parser = date_pattern ^ (any() >> date_parser)

(这里的组合符 @generate def date_with_prefix(): matched = yield(any() >> date_parser) return matched date_parser = date_pattern ^ date_with_prefix 表示 ^,您可以在文档中找到它。)

然后它会按预期工作:

try_choice

为了避免对无效输入的期望并返回 >>> date_parser.parse("Lorem ipsum dolor sit amet.") --------------------------------------------------------------------------- ParseError Traceback (most recent call last) ... ParseError: expected date_with_prefix at 0:27 >>> date_parser.parse("A number 42 is present here.") --------------------------------------------------------------------------- ParseError Traceback (most recent call last) ... ParseError: expected date_with_prefix at 0:28 >>> date_parser.parse("But here is a date 11/05/2017. Can you extract this?") '11/05/2017' ,您可以将其定义为 None 解析器:

optional

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。