需求
从不方便透露的网站爬取了一批商品数据,需要从商品名中获取规格。规格可能以 “ml”、“g”、“pcs” 等单位表示,也可能带有乘积符号 “x”(如 “2x30ml”),或者是多个规格组合(如 “50ml + 30ml”)。大概就是下面这种样子
List<String> strings = Lists.newArrayList(
"幸运润手霜八支装 8x30ml",
"赋能焕采眼霜 双瓶装 2x1.5g",
"赋能焕采眼霜 双瓶装 2x1.5g + 50g",
"多方位pitera™ 保湿修护套组 2x2.30ml + 100ml",
"特润修护肌活精华露和充盈紧弹眼霜套装 50ml + 15ml",
"紫胖子卸妆膏(面部及眼部卸妆霜) 12.5ml + 30ml + 15ml",
"紫胖子卸妆膏(面部及眼部卸妆霜) 1.25g + 30mg + 15mg",
"夜间密集修护套装 150ml + 100ml + 50ml + 75ml + 15ml",
"夜间密集修护套装 150mg + 100mg + 50mg + 75mg + 15mg",
"海蓝之谜修护精萃沁润面膜 保湿修护面膜 27.5g",
"海蓝之谜修护精萃沁润面膜 保湿修护面膜 27.5Pcs",
"海蓝之谜修护精萃沁润面膜 保湿修护面膜 27pcs 27pcs",
"海蓝之谜修护精萃沁润面膜 保湿修护面膜 27.5ML 27.5ml",
"海蓝之谜修护精萃沁润面膜 保湿修护面膜 #128",
"Dior Rouge Forever Stick 3.2g 729 Cool Taupe",
"Dior Prestige Le Micro Fluid Teint De Rose Foundation Illuminateur Spf25 30ml 1N Neutral",
"护肤面膜 两盒装 2x10 pcs"
);
代码实现
使用正则表达式匹配:import com.google.common.collect.Lists;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @date 2024/9/13 16:42
* @description:
*/
public class DemoController {
private static final Pattern PATTERN = Pattern.compile("(\\d+(?:\\.\\d+)?\\s*(?:x\\s*\\d+(?:\\.\\d+)?)?\\s*(?:ml|g|pcs|l|cl|mg|kg)\\s*(?:\\+\\s*)?|#\\d+\\s*)+", Pattern.CASE_INSENSITIVE);
public static void main(String[] args) {
List<String> strings = Lists.newArrayList("幸运润手霜八支装 8x30ml",
"赋能焕采眼霜 双瓶装 2x1.5g",
"赋能焕采眼霜 双瓶装 2x1.5g + 50g",
"多方位pitera™ 保湿修护套组 2x2.30ml + 100ml",
"特润修护肌活精华露和充盈紧弹眼霜套装 50ml + 15ml",
"紫胖子卸妆膏(面部及眼部卸妆霜) 12.5ml + 30ml + 15ml",
"紫胖子卸妆膏(面部及眼部卸妆霜) 1.25g + 30mg + 15mg",
"夜间密集修护套装 150ml + 100ml + 50ml + 75ml + 15ml ",
"夜间密集修护套装 150mg + 100mg + 50mg + 75mg + 15mg ",
"海蓝之谜修护精萃沁润面膜 保湿修护面膜 27.5g",
"海蓝之谜修护精萃沁润面膜 保湿修护面膜 27.5Pcs",
"海蓝之谜修护精萃沁润面膜 保湿修护面膜 27pcs 27pcs",
"海蓝之谜修护精萃沁润面膜 保湿修护面膜 27.5ML 27.5ml",
"海蓝之谜修护精萃沁润面膜 保湿修护面膜 #128",
"Dior Rouge Forever Stick 3.2g 729 Cool Taupe",
"Dior Prestige Le Micro Fluid Teint De Rose Foundation Illuminateur Spf25 30ml 1N Neutral",
"护肤面膜 两盒装 2x10 pcs");
for (String string : strings) {
String specification = "";
Matcher matcher = PATTERN.matcher(string);
if (matcher.find()) {
// 如果匹配成功,打印出规格
specification = matcher.group();
// 去重规格项
specification = removeDuplicates(specification);
}
System.out.println("name: " + string + " >>>>>> 规格 " + specification);
}
}
// 去重并保持原有顺序
private static String removeDuplicates(String specification) {
if (specification.contains("+") || specification.contains("x")) {
return specification;
}
String[] parts = specification.split("\\s+");
Set<String> uniqueParts = new LinkedHashSet<>();
for (String part : parts) {
uniqueParts.add(part.toLowerCase());
}
return String.join(" ", uniqueParts);
}
}
正则表达式分析:
- 正则表达式匹配规则
\\d+(?:\\.\\d+)?
: 匹配整数或小数,如 “8” 或 “8.5”。(?:x\\s*\\d+(?:\\.\\d+)?)?
: 匹配乘积符号 “x” 和数量,如 “2x30ml”。(ml|g|pcs|l|cl|mg|kg)
: 匹配常见的规格单位,如 “ml”、“g”、“pcs” 等。(\\+\\s*)?
: 匹配加号 “+”,表示多个规格组合,如 “50ml + 30ml”。
- 匹配逻辑
- 使用
matcher.find()
方法查找商品名称中的规格部分。匹配成功后,提取规格信息。 - 将匹配到的规格字符串传入
removeDuplicates
方法中,进行去重处理。
- 去重逻辑
- 使用
LinkedHashSet
来去重并保持原有顺序。将规格字符串按空格分隔后,逐一加入LinkedHashSet
中,最终通过String.join()
将去重后的部分拼接起来。
输出结果:
name: 幸运润手霜八支装 8x30ml >>>>>> 规格 8x30ml
name: 赋能焕采眼霜 双瓶装 2x1.5g >>>>>> 规格 2x1.5g
name: 赋能焕采眼霜 双瓶装 2x1.5g + 50g >>>>>> 规格 2x1.5g + 50g
name: 多方位pitera™ 保湿修护套组 2x2.30ml + 100ml >>>>>> 规格 2x2.30ml + 100ml
name: 特润修护肌活精华露和充盈紧弹眼霜套装 50ml + 15ml >>>>>> 规格 50ml + 15ml
name: 紫胖子卸妆膏(面部及眼部卸妆霜) 12.5ml + 30ml + 15ml >>>>>> 规格 12.5ml + 30ml + 15ml
name: 紫胖子卸妆膏(面部及眼部卸妆霜) 1.25g + 30mg + 15mg >>>>>> 规格 1.25g + 30mg + 15mg
name: 夜间密集修护套装 150ml + 100ml + 50ml + 75ml + 15ml >>>>>> 规格 150ml + 100ml + 50ml + 75ml + 15ml
name: 夜间密集修护套装 150mg + 100mg + 50mg + 75mg + 15mg >>>>>> 规格 150mg + 100mg + 50mg + 75mg + 15mg
name: 海蓝之谜修护精萃沁润面膜 保湿修护面膜 27.5g >>>>>> 规格 27.5g
name: 海蓝之谜修护精萃沁润面膜 保湿修护面膜 27.5Pcs >>>>>> 规格 27.5pcs
name: 海蓝之谜修护精萃沁润面膜 保湿修护面膜 27pcs 27pcs >>>>>> 规格 27pcs
name: 海蓝之谜修护精萃沁润面膜 保湿修护面膜 27.5ML 27.5ml >>>>>> 规格 27.5ml
name: 海蓝之谜修护精萃沁润面膜 保湿修护面膜 #128 >>>>>> 规格 #128
name: Dior Rouge Forever Stick 3.2g 729 Cool Taupe >>>>>> 规格 3.2g
name: Dior Prestige Le Micro Fluid Teint De Rose Foundation Illuminateur Spf25 30ml 1N Neutral >>>>>> 规格 30ml
name: 护肤面膜 两盒装 2x10 pcs >>>>>> 规格 2x10 pcs
我当然不会试图摘月,我要月亮奔我而来。 --奥黛丽·赫本