可以将正则表达式合并为最后一个单词和数字吗?

时间:2019-07-31 02:17:39

标签: php regex

我有一个示例字符串,例如

September 14-20, 26, 28-30, October 1-8, 10, 11, 15-20, 24, November 25, 28-30

使用(\w+)$时,它将捕获30。是否可以使用单个表达式同时捕获November30

6 个答案:

答案 0 :(得分:2)

一种不同的方法,不管是好是坏(我认为),都是将字符串分成多个部分,然后选择所需的内容。
这样做的好处是可以将它们全部排列在一起,因此您可以很容易地选择其他月份和日期。

$str = 'September 14-20, 26, 28-30, October 1-8, 10, 11, 15-20, 24, November 25, 28-30';

//Explode on [' ', ',', ', ', '-']    
$arr = explode(" ", str_replace(['-', ', '], ' ', $str));
$months = preg_grep("/\D+/", $arr); // find the months

$LastMonth = end($months);
$LastDay = end($arr);
var_dump($LastMonth, $LastDay); //November, 30

https://3v4l.org/GiqtI


也可以这样写:您可以使用substr和strpos重新创建完整的月份字符串或选择范围(28-30)中的最后几天,或者像这样发布最后一个月:
https://3v4l.org/PBAXU

答案 1 :(得分:2)

考虑到示例字符串的格式,您可以使用重复组并使用2个捕获组,其中第一个包含月份名称,第二个包含最后一个1位数或更多位数字

^(?:[A-Za-z]+ \d+(?:-\d+)?(?:, \d+(?:-\d+)?)*, )*([A-Za-z]+)(?: \d+(?:-\d+)?,)* (?:\d+-)?(\d+)$

说明

  • ^字符串的开头
  • (?:非捕获组
    • [A-Za-z]+ \d+匹配1+ a-zA-Z,空格和1+个数字
    • (?:-\d+)?(可选)匹配连字符和1个以上的数字
    • (?:, \d+(?:-\d+)?)*, 重复0+次以匹配逗号,1 +个数字,以及可选的连字符和1+个数字
  • )*关闭非捕获组,重复0次以上
  • (捕获组1
    • [A-Za-z]+)(?: \d+(?:-\d+)?,
  • )* 关闭第1组,重复0次以上并匹配一个空格
  • (?:\d+-)?匹配可选的1+数字和连字符
  • (\d+)捕获第2组,匹配1个以上的数字
  • $字符串结尾

Regex demo

答案 2 :(得分:1)

您可以使用

([A-Za-z]+)[\d, -]+?(\d+)$

enter image description here

Demo


响应@lufac条评论

([A-Za-z]+)[^-]+-(\d+)$

Demo


如果最后一个数字之前的-也不总是在那里,则可以使用

([A-Za-z]+)[^a-zA-z]+?(\d+)$

Demo

答案 3 :(得分:1)

我们可以在此处尝试使用preg_match

$input = "September 14-20, 26, 28-30, October 1-8, 10, 11, 15-20, 24, November 25, 28-30";
preg_match('/.*\b([A-Za-z]+).*\b(\d+)$/', $input, $matches);
echo "month is: " . $matches[1] . "\n";
echo "last day is: " . $matches[2];

此打印:

month is: November
last day is: 30

答案 4 :(得分:1)

这是更详细的正则表达式。它的针对性也更高,如果以后需要更多信息,您可以轻松对其进行修改:

$input = 'September 14-20, 26, 28-30, October 1-8, 10, 11, 15-20, 24, November 25, 28-30';
$num_matches = preg_match_all('~(?P<schedule>(?P<month>[A-Za-z]+?) (((\d{1,2}-)?(?P<endDate>\d{1,2}))(?:, )?)+)~', $input, $matches);
var_dump(
    array_pop($matches['schedule']),
    array_pop($matches['month']),
    array_pop($matches['endDate'])
);

它利用命名组,使从$matches提取所需数据变得非常容易。

由于只需要最后一个月及其结束日期,因此只需弹出每个已命名组的最后一个值。

您会得到:

string(18) "November 25, 28-30"
string(8) "November"
string(2) "30"

Demo link

答案 5 :(得分:0)

([a-zA-Z]+)[^a-zA-Z]+?([\d]+)$

单词,不是单词,数字。

https://regex101.com/r/nFIc9H/1