Android Studio Java食谱有效数字及对应食材正则提取问题
Android Studio(Java)食谱APP食材数字与词汇匹配方案
核心需求回顾
- 从TXT文件提取整数/小数数字,排除温度(带°C,有无空格均可)、时长(带时/分/秒,有无空格均可)类数字
- 单独匹配数字、对应单位(如果有)、食材词汇,支持数字与单位无空格的情况(如
10ml milk) - 保留温度、时长类数字不做处理
正则表达式设计
针对需求,设计带负向断言的正则,用于精准匹配目标内容:
String regex = "(?<!\\d)(\\d+\\.?\\d*)(?!\\s*(?:°C|时|分|秒))\\s*(?:([a-zA-Z]+)\\s*)?(\\w+)";
正则各部分解释
(?<!\\d):负向零宽断言,确保数字前无其他数字,避免匹配数字片段(如123中的23)(\\d+\\.?\\d*):捕获组1,匹配整数或小数(如3、10.5、0.75)(?!\\s*(?:°C|时|分|秒)):负向零宽断言,排除数字后紧跟(可选空格)温度/时长单位的情况\\s*:匹配数字与后续内容间的可选空格(?:([a-zA-Z]+)\\s*)?:非捕获组包裹捕获组2,匹配可选的无空格单位(如ml、g、cup),单位后允许空格(\\w+):捕获组3,匹配食材核心词汇(如eggs、milk、flour)
Java代码实现示例
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RecipeIngredientParser { public static void parseIngredients(String recipeText) { // 正则表达式,注意Java中转义符需双写 String regex = "(?<!\\d)(\\d+\\.?\\d*)(?!\\s*(?:°C|时|分|秒))\\s*(?:([a-zA-Z]+)\\s*)?(\\w+)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(recipeText); while (matcher.find()) { String quantity = matcher.group(1); String unit = matcher.group(2); // 无单位时返回null String ingredient = matcher.group(3); // 输出提取结果,可根据需求存入实体类或更新UI System.out.printf("提取结果:数量=%s,单位=%s,食材=%s%n", quantity, unit == null ? "无" : unit, ingredient); } } public static void main(String[] args) { // 测试文本,包含食材列表和步骤内容 String testRecipe = "食材:3 eggs,10ml milk,2.5g flour\n步骤:将100°C的水倒入碗中,加入15ml honey,搅拌5分钟后静置"; parseIngredients(testRecipe); } }
代码说明
- 遍历匹配结果时,通过
group(1)获取数字数量,group(2)获取单位(无则为null),group(3)获取食材词汇 - 温度(
100°C)、时长(5分钟)类数字会被负向断言排除,不会被匹配
关键问题解决
- 数字与单位无空格匹配:正则中
\\s*(?:([a-zA-Z]+)\\s*)?允许数字后直接跟单位(\\s*为可选空格),解决10ml milk这类场景的匹配问题 - 精准排除温度/时长数字:通过
(?!\\s*(?:°C|时|分|秒))断言,无论数字与单位间有无空格,都会被排除
内容的提问来源于stack exchange,提问作者Armin Grobbelaar
相关产品推荐
相关产品推荐

