将含后向断言的正则表达式转换为Safari兼容版本求助
问题描述
- 需求:将食谱配料列表拆分为单个配料项
- 原使用正则表达式:
/(?<!\d)\s(?=(?<!x)\d(?![x]))/gm,但Safari不支持后向断言导致无法生效 - 示例文本:
1 cup water 1 Tablespoon salt 1 stick (4 oz) butter 1 cup flour 4 eggs 1 small head cauliflower (1 1/2 lbs), cut in 1" florets 10 salted anchovies, filleted, rinse twice (opt) 2 quarts olive oil, heat to 375F
兼容Safari的解决方案
由于Safari(尤其是旧版本)不支持ES2018引入的后向断言,可采用以下两种替代思路实现配料拆分:
方案1:替换拆分法
通过匹配符合拆分条件的空格,替换为特殊分隔符后拆分,正则无需依赖后向断言:
const input = "1 cup water 1 Tablespoon salt 1 stick (4 oz) butter 1 cup flour 4 eggs 1 small head cauliflower (1 1/2 lbs), cut in 1\" florets 10 salted anchovies, filleted, rinse twice (opt) 2 quarts olive oil, heat to 375F"; const splitRegex = /(\D)(\s)(?=\d(?!x))/g; const ingredients = input.replace(splitRegex, '$1|').split('|');
正则说明
(\D):捕获一个非数字字符,确保拆分位置前不是数字,避免破坏1 1/2这类带分数的格式(\s):匹配需要替换的目标空格(?=\d(?!x)):正向断言,确保空格后是数字且后续不是x,避免误拆分1x这类组合
方案2:直接提取法
跳过拆分步骤,直接匹配所有完整的配料项:
const input = "1 cup water 1 Tablespoon salt 1 stick (4 oz) butter 1 cup flour 4 eggs 1 small head cauliflower (1 1/2 lbs), cut in 1\" florets 10 salted anchovies, filleted, rinse twice (opt) 2 quarts olive oil, heat to 375F"; const matchRegex = /\d+(?:\s+\d+\/\d+)?(?:\s+\w+)*\s+.+?(?=\s+\d(?!x)|$)/g; const ingredients = input.match(matchRegex);
正则说明
\d+(?:\s+\d+\/\d+)?:匹配配料数量,兼容整数(如1)和分数(如1 1/2)格式(?:\s+\w+)*:匹配数量后的单位(如cup、Tablespoon)\s+.+?:匹配配料名称及后续附加描述(?=\s+\d(?!x)|$):正向断言,限定匹配范围到下一个数字开头的配料或文本结尾
两种方案均可得到正确拆分结果:
- 1 cup water
- 1 Tablespoon salt
- 1 stick (4 oz) butter
- 1 cup flour
- 4 eggs
- 1 small head cauliflower (1 1/2 lbs), cut in 1" florets
- 10 salted anchovies, filleted, rinse twice (opt)
- 2 quarts olive oil, heat to 375F
内容的提问来源于stack exchange,提问作者Bingerminn
相关产品推荐
相关产品推荐

