问题描述
我有一个关于使用 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