我目前正在为一家杂货店构建一个 JavaScript 网络抓取工具,用于处理产品标题,然后返回产品的商品数量、数量和每升价格。大多数产品标题看起来像这样:
可口可乐( Vanilla 味)12 x 330 mL
为了获取有关该产品的元数据,我编写了一个正则表达式。它将查找单词边界,后跟 1 或 2 位数字、空格、字符串“x”、另一个空格,最后是 1、2 或 3 位数字:
const filter = new RegExp(/\b\d{1,2}\sx\s\d{1,3}/);
然后,我测试每个结果是否与正则表达式匹配,然后计算商品数量、商品体积、体积(升)以及每升的价格。
if (result.title.match(filter)) {
result.itemCount = parseInt(result.title.match(/\d{1}\s/));
result.itemVolume = parseInt(result.title.match(/\d{2,3}\s/));
result.litreVolume = (result.itemCount * result.itemVolume) / 1000;
result.pricePerLitre = +(result.price / result.litreVolume).toFixed(2);
} else {
result.itemCount = 1;
result.itemVolume = parseInt(result.title.match(/\d{2,3}\s/));
result.litreVolume = result.itemVolume / 1000;
result.pricePerLitre = +(result.price / result.litreVolume).toFixed(2);
}
90% 的结果看起来不错,但有时我会得到意想不到的结果。例如:
- NaN 的项目计数,这可能与某些标题包含更多数字有关(Coca Cola (4-Way) 12 x 330 mL))
- 无限卷
- 每升的价格太高
显然,我计算所需元数据的方法出了问题。使用 RegEx 进行计算的更好方法是什么?我是否遗漏了一些使我的计算不易出错的东西?
最佳答案
如果我理解正确,过滤器 \b\d{1,2}\sx\s\d{1,3}
有效,但您的子过滤器不起作用(\d{ 1}\s
)...
我只习惯在 c# 中使用正则表达式,但是,我看到你也可以在 java 中使用组。
将模式更改为 (\b\d{1,2})\sx\s(\d{1,3})
。当您在正则表达式中放入括号时,该部分将成为您随后可以访问的组。
正如我所说,我已经有几年没有使用 java 了,但我从网络上挑选了这个代码片段。它展示了如何在 java 中使用组。作为模式,您应该使用 (\b\d{1,2})\sx\s(\d{1,3})
。如果与 c# 中的相同,则 group(0) 是整个结果,group(1) 是您的第一个实际组,group(2) 是第二个。
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find( )) {
System.out.println("Found value: " + m.group(0) );
System.out.println("Found value: " + m.group(1) );
}
我认为你可以用比上面提到的更少的代码来编写它,但你明白了;-)
关于javascript - 使用正则表达式查找体积和项目数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59609861/