求助构建匹配含数字俱乐部名的足球积分榜正则表达式
足球积分榜正则匹配解决方案
问题场景
有如下自由格式的足球积分榜文本:
1 Cibalia Vinkovci 0 30 21 5 4 67 24 43 68 [promoted] 2 Vihor Jelisavac 0 30 16 6 8 44 29 15 54 3 Cepin 0 30 14 7 9 49 29 20 49 4 Belisce 0 30 14 6 10 53 39 14 48 5 Mladost Zdralovi 0 30 13 8 9 48 35 13 47 [moved to group "North"] 6 Slavonija Pozega 0 30 12 7 11 45 40 5 43 7 Marsonia Slavonski Brod 0 30 12 6 12 38 40 -2 42 8 Zrinski Jurjevac 0 30 11 8 11 35 35 0 41 14 Vukovar 1991 0 30 8 7 15 29 52 -23 31
现有正则方案存在两个问题:
- 正则
(\d+)\s+([A-Za-z\s]+)(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)仅能匹配最多两个不含数字的俱乐部名,对第7行(含三个单词)、第14行(含数字)的俱乐部名匹配失效; - 将数字加入俱乐部名匹配组后,正则
(\d+)\s+([A-Za-z0-9\s]+)(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)会因贪婪匹配溢出,错误包含后续数字字段。
期望匹配结果示例:match = [ '14','Vukovar 1991','0','30','8','7','15','29','52','-23','31' ]
解决思路与正则方案
核心是利用俱乐部名后紧跟固定格式数字字段的规律,通过非贪婪匹配+精确字段匹配避免溢出。
方案1:正向预查限定俱乐部名边界
正则表达式(支持负数字段):
^(\d+)\s+([\w\s]+?)(?=\s+-?\d)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)
各部分解释:
^(\d+):匹配行首的排名数字;\s+:匹配排名与俱乐部名之间的空格;([\w\s]+?):非贪婪匹配俱乐部名(\w覆盖字母、数字,+?避免过度匹配);(?=\s+-?\d):正向预查,确保俱乐部名后紧跟空格+数字(含负数),以此作为俱乐部名的结束标记;(-?\d+):依次匹配剩余的数字字段,-?支持负数(如净胜球-23)。
方案2:固定数字字段反向推导
利用每行数字字段数量固定的特点,先匹配末尾的数字字段,反向锁定俱乐部名范围:
^(\d+)\s+(.+?)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)$
各部分解释:
^(\d+):行首排名;(.+?):非贪婪匹配任意字符(覆盖字母、数字、空格),直到遇到后续数字字段;(-?\d+):匹配固定数量的9个数字字段;$:匹配行尾,自动忽略[promoted]这类行尾备注。
效果验证
两种方案均能正确匹配所有行的内容,比如第14行会得到期望的匹配数组:['14','Vukovar 1991','0','30','8','7','15','29','52','-23','31'],同时支持多单词、含数字的俱乐部名,不会出现溢出匹配问题。
内容的提问来源于stack exchange,提问作者Hogar
相关产品推荐
相关产品推荐

