2

我正在尝试匹配 http 请求的以下接受语言标头字段。

var regex = /([^-]*)(?:-([^;]*))?(?:;q=([0-9].[0-9]))?/
"en-us;q=0.8".match(regex) => ["en-us;q=0.8", "en", "us", "0.8"]
"en".match(regex) => ["en", "en", undefined, undefined]
"en;q=0.8".match(regex) => ["en;q=0.8", "en;q=0.8", undefined, undefined]

问题出在最后一行。它应该恕我直言:

["en;q=0.8", "en", "0.8", undefined]

我的正则表达式有什么问题?

4

2 回答 2

2

您的第一个捕获组匹配不包含破折号的所有内容并在 dash 处停止-。在您的最后一个字符串中,您没有破折号,因此它与整个字符串匹配。正则表达式的其他部分是可选的,因此它们不匹配。

您可以通过不允许;在您的第一个捕获组中来解决这种特殊情况:

/([^-;]*)(?:-([^;]*))?(?:;q=([0-9]\.[0-9]))?/

PS:我还在最后一个捕获组中修复了您的点。它匹配任何字符,现在它只匹配.字符。

于 2013-11-07T12:21:06.753 回答
1

由于@ioquatix 从未提交更好地遵循RFC3066 第 2.1 节的答案,因此我发布的版本应该更符合标准:

/^((?<primary>\*|([A-Z]{1,8}))((?<!\*)-(?<subtag>[A-Z0-9]{1,8}))?)(;q=(?<quality>1|0|0.[0-9]{1,3}))?$/i
于 2020-10-12T16:15:17.170 回答