【问题标题】:Are universal characters allowed in PHP explode()PHPexplode() 中是否允许使用通用字符
【发布时间】:2012-05-27 14:29:04
【问题描述】:

我需要在“2012 年 5 月 27 日星期日早上 6 点 25 分”之前获取所有内容

我希望在“On xxx, xxx xx, xxxx at xx:xx xx”之前得到一切,

这里的问题是,5 月、27 日和 6 日的长度都是可变的。什么是这项工作的最佳工具。由于我缺乏正则表达式的经验,我正在尝试使用explode(),但它似乎不能在这里完成这项工作。正则表达式是我的最佳选择吗?

[编辑]

我最终使用了多种答案。我去了:

preg_match("/(.*)On\s+(Sun|Sat|Fri|Thu|Wed|Tue|Mon),\s+(一月|二月|三月|四月|五月|六月|七月|八月|九月|十月|十一月|十二月)\s+\d?\d,\s+\d{4}\s+at\s+\d?\d:\d\d\s+[AP]M,/i", $到,$end);

【问题讨论】:

  • 为什么不将 strtotime() 与 date() 结合使用?
  • 我还是不明白你在做什么。
  • 充满值的字符串中的“之前”在哪里?
  • 抱歉,不清楚。我正在尝试解析来自将 $_POST 密钥发送到我的脚本的外部服务器的电子邮件。我需要回复消息,但它与原始消息混淆。我能想到得到回复消息的唯一方法是在我上面放的东西之前抓住一切。
  • 所以你有一个像这样的数据集“XXXXXXXXXX On Sun, May 27, 2012 at 6:25 AM”,你想得到 XXXXXXXXXX 吗?

标签: php regex


【解决方案1】:

我猜是这样的:

/On\s+(Sun|Sat|Fri|Thu|Wed|Tue|Mon),\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s+\d?\d,\s+\d{4}\s+at\s+\d?\d:\d\d\s+[AP]M,/i

[编辑]

根据评论:我添加了对不区分大小写的支持(通过将i 修饰符添加到正则表达式的末尾)。我还将表达式中的空格更改为\s 以允许任何空白字符,并添加+ 以允许单词之间有多个空格。

我没有将其更改为支持长日期名称或短月份名称,因为问题指定月份名称的长度是可变的,但没有将日期名称指定为可变的。但是,如果需要,添加这些变体应该很简单。

[编辑]

$to = "Let me know how this response looks..... On Sun, May 27, 2012 at 6:25 AM, Pr";
preg_match("/On\s+(Sun|Sat|Fri|Thu|Wed|Tue|Mon),\s+(January|February|March|April|May|June|July|August|September|October|November|December)\s+\d?\d,\s+\d{4}\s+at\s+\d?\d:\d\d\s+[AP]M,/i", $to, $end);

此代码适用于您评论中给出的示例。

希望对您有所帮助。

【讨论】:

  • 您应该支持:短名和全名(SunSundayJanJanuary)、大写/小写和多个空格。
  • @bsdnoobz - 我在回答具体问题,而不是提供通用日期正则表达式。星期几不是他指定为可变长度的字段之一,所以我假设它固定为三个字符。相反,尽管“May”在这一点上可能含糊不清,但月份被指定为可变长度,因此我提供了完整的月份名称。问题中也没有提到空格,所以我认为它是固定的(如果他从单个特定来源获取输入,可能会是这样)。
  • @bsdnoobz - 我已经用你的 一些 建议编辑了答案(尽管我怀疑这样做更多是为了安抚你而不是为了 OP)
  • 感谢您的帮助 Spudley。我正在努力让您的解决方案发挥作用。我正在使用以下内容,但没有找到 $to 的匹配项 =“让我知道此响应的外观.....2012 年 5 月 27 日星期日上午 6 点 25 分,Pr” preg_match("/On\s+ (周日|周六|周五|周四|周三|周二|周一)\s+(一月|二月|三月|四月|五月|六月|七月|八月|九月|十月|十一月|十二月)\s+\d?\d, \s+\d{4}\s+at\s+\d?\d:\d\d\s+[AP]M,/i", $to, $end);回声“结束 0”。 $end[0];
  • @DevNewb - 主要问题是我在星期几之后错过了逗号。我已经修复了正则表达式并将您评论中的代码的工作版本粘贴到答案中。
【解决方案2】:
preg_match('/(.*?) On \w+, \w+ \d?\d, \d+ at \d?\d:\d?\d \w\w,/', 'grab this text here On Sun, May 27, 2012 at 6:25 AM,', $matches);
echo $matches[1];
// echoes 'grab this text here'

(.*?) 匹配开头的所有内容,\w+ 匹配任何字母数字字符 1 次或多次,\d?\d 匹配一个或两个数字

【讨论】:

    【解决方案3】:

    一个正则表达式会起作用,因为它就是为此而生的:根据模式选择数据。但是,您可以在“,”(逗号)上爆炸,然后将前 4 个元素再次内爆在一起以形成您的句子。我怀疑在这种情况下使用正则表达式会更快。

    最终,这是您的偏好:您更容易阅读和理解。 在这种特殊情况下,正则表达式的主要优势是它们可以提取特定的值/模式,因此您可以轻松地将它们留出例如月份。

    $dateString = "On Sun, May 27, 2012 at 6:25 AM, some other text here";
    
    // using explode/implode
    $result = explode(',',$dateString);
    
    print "we got: " . implode(',', array_slice($result,0,3)) . "\n";
    
    // using regular expression
    $pattern = "/On [A-Z,a-z]{3}, [A-Z,a-z]{3} [0-9]+, [0-9]{4} at [0-9,:]+ (?:A|P)M/U";
    
    preg_match($pattern,$dateString,$match);
    
    print "We got: " . $match[0] . "\n";
    

    请同时阅读PHP manual, Regular Expressions subsection 和首字母tutorial

    在这种情况下,我个人认为 reg exp 可能在视觉和性能方面都过分了。不过一定要学习正则表达式,它们有时会很有帮助。

    【讨论】:

    • 我做错了什么吗? $match[0] 返回 2012 年 5 月 27 日星期日上午 7:48?我需要在它返回之前的一切。
    • 哦,那是我的错误,我将您的请求误解为想要获得日期字符串。对不起。在这种情况下,您需要使用带有提取$pattern = "/(.*)On [A-Z,a-z]{3}, [A-Z,a-z]{3} [0-9]+, [0-9]{4} at [0-9,:]+ (?:A|P)M/U"; preg_match($pattern,$dateString,$match); print "We got: " . $match[1] . "\n"; 的模式匹配并调整匹配。对不起,如果我让你感到困惑。
    • /(reg exp 的开始)和 On 之间的 (.*) 发生了变化,这意味着您希望捕获任何数据(.)无限次(*)(在括号之间)和结果放在 $match 数组中(第一个条目是整个字符串,第二个条目是第一个匹配项)
    猜你喜欢
    • 2012-08-04
    • 2015-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多