Java中如何区分图片识别的字符串与整数并分类存储?
问题背景
从图片识别食谱文本,内容包含字符串(食材名称)和整数(食材数量),但现有代码无法区分类型,所有内容都被判定为字符串,需要实现分类存储到包含字符串、整数的集合中。
初始代码与问题
遍历识别文本的代码:
String elementText = ""; for (Text.Element element : line.getElements()) { elementText = element.getText(); Point[] elementCornerPoints = element.getCornerPoints(); Rect elementFrame = element.getBoundingBox(); checkObject(elementText); }
类型判断方法checkObject:
private void checkObject(Object obj) { if(obj instanceof Integer){ Log.d("log int", String.valueOf(obj)); Log.d("log int", "it's a number"); } else if(obj instanceof String){ Log.d("log string", (String)obj); Log.d("log string", "it's a string"); } }
日志输出显示所有内容(包括数字50、120)均被判定为字符串:
10:21:40.532 D oil
10:21:40.532 D it's a string
10:21:40.534 D garlic
10:21:40.534 D it's a string
10:21:40.537 D oregan
10:21:40.537 D it's a string
10:21:40.545 D 50
10:21:40.545 D it's a string
10:21:40.545 D g
10:21:40.545 D it's a string
10:21:40.545 D 120
10:21:40.545 D it's a string
更新后的尝试与新问题
尝试的check方法可正确识别整数并加入列表,但IsInt_ByRegex方法仍将整数判定为字符串:
check方法代码:
private void check(String elementText){ try{ int num = Integer.parseInt(this.elementText); Log.d("LOG int", "int " + num); list.add(num); Log.d("LOG int", "List " + list); //List [1, 2, 120, 50] } catch (NumberFormatException e) { // not an integer! } }
IsInt_ByRegex方法代码:
private void IsInt_ByRegex(String elementText) { try{ elementText.matches("/{[a-zA-Z]+}/"); Log.d("LOG string", "string " + elementText); }catch (Exception e){ } }
对应日志输出:
22:25:56.674 D string 50
22:25:56.649 D string red
22:25:56.649 D string peppers
22:25:56.654 D string 120
解决方案
核心问题分析
- 初始代码中
checkObject接收的参数是String类型(element.getText()返回值为字符串),因此instanceof Integer永远不成立,所有内容都会进入字符串分支。 - 更新后的
IsInt_ByRegex方法正则表达式错误:Java的matches方法不需要首尾/分隔符,且该正则逻辑颠倒,用于匹配字母内容而非整数。
可行实现方案
1. 定义数据存储结构
自定义类存储分类数据(比直接用ArrayList<Object>更清晰):
// 食谱成分类,区分名称(字符串)和数量(整数) class Ingredient { private String name; private Integer quantity; // 构造方法:存储食材名称 public Ingredient(String name) { this.name = name; } // 构造方法:存储食材数量 public Ingredient(Integer quantity) { this.quantity = quantity; } // Getter方法 public String getName() { return name; } public Integer getQuantity() { return quantity; } }
声明存储列表:
private ArrayList<Ingredient> ingredientList = new ArrayList<>();
2. 正确的类型判断方法
方法一:用Integer.parseInt捕获异常(推荐,可靠性更高)
private void processElementText(String elementText) { // 去除字符串前后空格,避免识别带空格的数字失败 String trimmedText = elementText.trim(); try { int num = Integer.parseInt(trimmedText); // 识别为整数,添加到列表 ingredientList.add(new Ingredient(num)); Log.d("LOG int", "int " + num); } catch (NumberFormatException e) { // 识别为字符串,添加到列表 ingredientList.add(new Ingredient(trimmedText)); Log.d("LOG string", "string " + trimmedText); } }
方法二:修正正则表达式判断整数
如果使用正则,正确的整数匹配规则如下:
private void processElementTextByRegex(String elementText) { String trimmedText = elementText.trim(); // 匹配正整数(需支持负整数则改为^-?\\d+$) if (trimmedText.matches("^\\d+$")) { int num = Integer.parseInt(trimmedText); ingredientList.add(new Ingredient(num)); Log.d("LOG int", "int " + num); } else { ingredientList.add(new Ingredient(trimmedText)); Log.d("LOG string", "string " + trimmedText); } }
3. 修改遍历代码
替换原有的checkObject调用为上述处理方法:
String elementText = ""; for (Text.Element element : line.getElements()) { elementText = element.getText(); Point[] elementCornerPoints = element.getCornerPoints(); Rect elementFrame = element.getBoundingBox(); // 调用处理方法 processElementText(elementText); // 或使用正则版本 // processElementTextByRegex(elementText); }
关键注意点
- 不需要将
elementText的声明改为ArrayList,elementText仅作为临时存储单条识别文本的变量,分类逻辑在处理方法中完成。 - 处理文本前必须用
trim()去除前后空格,避免识别时的空格导致数字转换失败。 - Java中使用正则时无需添加首尾
/分隔符,直接编写正则内容即可。
内容的提问来源于stack exchange,提问作者Giovanni

