我有一个示例字符串,例如
September 14-20, 26, 28-30, October 1-8, 10, 11, 15-20, 24, November 25, 28-30
使用(\w+)$
时,它将捕获30
。是否可以使用单个表达式同时捕获November
和30
?
答案 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
答案 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个以上的数字$
字符串结尾答案 2 :(得分:1)
您可以使用
([A-Za-z]+)[\d, -]+?(\d+)$
响应@lufac
条评论
([A-Za-z]+)[^-]+-(\d+)$
如果最后一个数字之前的-
也不总是在那里,则可以使用
([A-Za-z]+)[^a-zA-z]+?(\d+)$
答案 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"
答案 5 :(得分:0)