如何修正PHP preg_match正则,匹配Season类词汇前后的季号?
解决preg_match匹配季号兼容关键词前后位置的问题
我之前也碰到过类似的需求,原代码的正则只处理了「Season类词汇在前、数字在后」的情况(比如Season 11),但你的目标字符串是数字在前、关键词在后(11 Season),自然匹配不到。我们可以通过调整正则的分支结构来解决这个问题。
解决方案代码
下面是修改后的代码,既能匹配关键词在后的情况,也能匹配关键词在前的情况:
$a = 'The Simpson 11 Season'; if (preg_match("/(?:(Season|Stagione|S|T)\s*(\d+)|(\d+)\s*(Season|Stagione|S|T))/i", $a, $matches)) { // 提取季号:取第一个非空的数字捕获组 $seasonNumber = !empty($matches[2]) ? $matches[2] : $matches[3]; echo "提取到的季号:" . $seasonNumber; }
正则逻辑拆解
我们把这个正则的结构拆开来看:
(?:...):非捕获组,用来分组但不会在$matches中生成多余的条目,只聚焦我们需要的数字。- 第一个分支
(Season|Stagione|S|T)\s*(\d+):匹配「关键词 + 任意空格(包括0个) + 数字」的经典格式,数字会被捕获到$matches[2]。 - 第二个分支
(\d+)\s*(Season|Stagione|S|T):匹配「数字 + 任意空格 + 关键词」的格式,数字会被捕获到$matches[3]。 /i:不区分大小写规则,所以season、SEASON、stagione这类变体都能匹配。
更简洁的可选写法
如果你不想处理多个捕获组,可以用正向/反向预查来确保数字和关键词关联,但不捕获关键词本身:
$a = 'The Simpson 11 Season'; if (preg_match("/(?<=(Season|Stagione|S|T)\s*)(\d+)|(\d+)(?=\s*(Season|Stagione|S|T))/i", $a, $matches)) { $seasonNumber = !empty($matches[2]) ? $matches[2] : $matches[3]; echo "提取到的季号:" . $seasonNumber; }
这里(?<=...)是反向预查(确保数字前面有关键词),(?=...)是正向预查(确保数字后面有关键词),同样能准确捕获到目标季号。
多场景测试验证
你可以测试这些典型字符串,都能正确提取季号:
The Simpson Season 11→ 11The Simpson 11 Season→ 11Family Guy S12→ 12Breaking Bad 13 Stagione→13T8→8
内容的提问来源于stack exchange,提问作者OhGodWhy
相关产品推荐
相关产品推荐

