1

我正在寻找一个在 PHP 中使用正则表达式来“逆向工程”已粘贴到多行文本框并发送到脚本进行处理的套用信函(当然是已知格式)的一个很好的例子。

因此,例如,让我们假设这是原始的纯文本输入(取自 USDA 新闻稿):

华盛顿,2010 年 4 月 5 日 - North American Bison Co-Op,新罗克福德,ND,正在召回大约 25,000 磅的整头牛头,其中包含可能没有完全切除扁桃体的舌头,这不符合要求美国农业部食品安全与检验局 (FSIS) 今天宣布,从所有年龄的牛身上切除扁桃体。

为清楚起见,作为变量的字段在下面突出显示:

[pr_city=]WASHINGTON[pr_date=]2010 年 4 月 5 日- [corp_name=]North American Bison Co-Op[corp_city=]New Rockford[corp_state=]ND,机构正在召回大约[amount=]25,000 英镑[product=] 包含可能没有完全切除扁桃体的舌头的整块牛肉头,这不符合要求[reason=] 从所有年龄的牛身上切除扁桃体的规定,美国农业部的食品安全和检验服务 (FSIS) 今天宣布。

我怎样才能有效地提取内容

  • 公关城市
  • pr_date
  • 公司名称
  • 公司城市
  • 公司状态
  • 数量
  • 产品
  • 原因

我的例子中的字段?

任何帮助将不胜感激,谢谢。

4

3 回答 3

4

好吧,适用于您的示例的正则表达式可能如下所示(引入换行符以保持该野兽的可读性,需要在使用前删除):

/^(?P<pr_city>[^,]+), (?P<pr_date>[^-]+) - (?P<corp_name>.*?), a 
(?P<corp_city>[^,]+), (?P<corp_state>[^,]+), establishment is 
recalling approximately (?P<amount>.*?) of (?P<product>.*?), 
which is not compliant with regulations that require (?P<reason>.*?), 
the U\.S\. Department of Agriculture\'s Food Safety and Inspection 
Service \(FSIS\) announced today\.$/

所以,在 PHP 中你可以做

if (preg_match('/^(?P<pr_city>[^,]+), (?P<pr_date>[^-]+) - (?P<corp_name>.*?), a (?P<corp_city>[^,]+), (?P<corp_state>[^,]+), establishment is recalling approximately (?P<amount>.*?) of (?P<product>.*?), which is not compliant with regulations that require (?P<reason>.*?), the U\.S\. Department of Agriculture\'s Food Safety and Inspection Service \(FSIS\) announced today\.$/', $subject, $regs)) {
    $prcity = $regs['pr_city'];
    $prdate = $regs['pr_date'];
    ... etc.
} else {
    $result = "";
}

这假设了几件事,例如没有换行符,并且输入是整个字符串(而不是必须从中提取此部分的较大字符串)。我试图对合法价值做出一些有意义的假设,但其他输入很有可能会破坏这一点。所以可能需要更多的测试用例。

于 2010-04-12T16:00:36.777 回答
2

如果周围的文本是不变的,那么像这样的部分正则表达式可以解决问题:

preg_match('/^(.*?), (.*?)- (.*?), a (.*?), (.*?), establishment is recalling approximately (.*?), which is not compliant with regulations that require (.*?), the U.S. Department of Agriculture's Food Safety and Inspection Service (FSIS) announced today./', $text, $matches);

$matches[1] = 'WASHINGTON';
$matches[2] = 'April 5, 2010';
$matches[3] = ... etc...

如果周围的文本发生变化,那么你最终会得到大量的错误匹配、没有匹配等......基本上你需要一个 AI 来解析/理解 PR 版本。

于 2010-04-12T16:00:55.443 回答
1

编辑: 请忽略这个疯狂的答案,因为其他两个更好。我可能应该删除它,但我会保留它以供参考。

我有一个可能可行的疯狂想法:通过添加标记从输入构建一个 XML 字符串,然后解析它。它可能看起来像这样(完全未经测试)的代码:

preg_replace('([^,]*), ([^-]*)- ...etc...', '<pr_city>\1</pr_city><pr_date>\2</pr_date> ...etc...');

之后解析 XML 是一个不必要的复杂过程,最好留给 PHP 文档:http ://www.php.net/manual/en/function.xml-parse.php 。

您还可以考虑使用此方法将其转换为 JSON,然后使用 json_decode() 对其进行解析。无论如何,您必须考虑输入中出现"标记和>符号时会发生什么。

一次只匹配和删除一段文本可能更容易。

于 2010-04-12T16:00:59.703 回答