对字符串使用replaceAll()方法替换 * ? + / | 等字符的时候会报以下异常

本文详细解释了在正则表达式中出现的悬空元字符'*'的问题,并提供了解决方法,即将其修改为'[*]'或'//*'。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Dangling meta character '*' near index 0

这主要是因为这些符号在正则表达示中有相应意义。

只需将其改为 [*]//* 即可。

package com.luxsan.service; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.hankcs.hanlp.HanLP; import com.hankcs.hanlp.seg.common.Term; import com.luxsan.common.core.utils.MessageUtils; import com.luxsan.domain.ValidationResult; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import net.sourceforge.tess4j.Tesseract; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.*; import java.util.regex.Pattern; @RequiredArgsConstructor @Service public class ReadFileContentService { private final ObjectMapper objectMapper = new ObjectMapper(); private Tesseract tesseract; @PostConstruct public void initOcrEngine() { tesseract = new Tesseract(); //语言包路径和支持语言 tesseract.setDatapath("D:\\maven_use\\lingxi-lhc\\lingxi-ai-extend\\lingxi-ai-comparison\\src\\main\\resources\\tessdata"); tesseract.setLanguage("eng+chi_sim"); tesseract.setPageSegMode(6); // 自动页面分割 tesseract.setOcrEngineMode(1); // LSTM引擎 } /** * 支持PDF读取文件和图片ocr */ public String extractContent(MultipartFile file) { String contentType = file.getContentType(); String fileName = file.getOriginalFilename().toLowerCase(); if (contentType == null) { return "不支持的文件类型: " + contentType; } if (fileName.endsWith(".pdf")) { return readPdfText(file); } return extractImageText(file); } /** * 读取PDF文本内容 * * @param file * @return */ public String readPdfText(MultipartFile file) { try (PDDocument doc = PDDocument.load(file.getInputStream())) { PDFTextStripper stripper = new PDFTextStripper(); // 设置行分隔符 stripper.setLineSeparator("\n"); // 设置字符间距 stripper.setSortByPosition(true); String rawText = stripper.getText(doc); System.out.println("pdf内容" + rawText); return rawText.trim(); } catch (Exception e) { return MessageUtils.message("file.read.pdf.error"); } } /** * OCR识别图片内容 */ private String extractImageText(MultipartFile file) { try (InputStream is = file.getInputStream()) { // 将输入流直接转为BufferedImage BufferedImage image = ImageIO.read(is); if (image == null) { return MessageUtils.message("Image.parsing.failed"); } // 直接对BufferedImage进行OCR String result = tesseract.doOCR(image).replaceAll("\\s+", " ").trim(); System.out.println("图片内容" + result); return result; } catch (Exception e) { return MessageUtils.message("file.read.picture.error"); } } /** * 解析json */ public JsonNode parseJson(String jsonContent) throws Exception { return this.objectMapper.readTree(jsonContent); } public List<ValidationResult> compareContent(String pdfText, JsonNode jsonConfig) { List<ValidationResult> results = new ArrayList<>(); // 统一转换为小写 String cleanPdf = pdfText.replaceAll("\\s+", "").toLowerCase(); //处理JSON结构对象/数组 JsonNode dataNode = jsonConfig.isArray() && jsonConfig.size() > 0 ? jsonConfig.get(0) : jsonConfig; // 高效遍历JSON字段 dataNode.fields().forEachRemaining(entry -> { String key = entry.getKey(); String value = entry.getValue().asText().replaceAll("\\s+", "").toLowerCase(); if (!value.isEmpty()) { boolean found = cleanPdf.contains(value); results.add(new ValidationResult( "FIELD", key, value, found ? "Found" : "Not Found", found )); } }); return results; } public JsonNode parsePipeSeparatedDataToJson(String inputData) throws Exception { Map<String, String> dataMap = parsePipeSeparatedData(inputData); return objectMapper.valueToTree(dataMap); } //解析分隔数据 public Map<String, String> parsePipeSeparatedData(String fileCONTENT) { //处理转义的换行符 fileCONTENT = fileCONTENT.replace("\\n", "\n").replaceAll("\\|+\"$", "").trim(); Map<String, String> dataMap = new LinkedHashMap<>(); String[] lines = fileCONTENT.split("\n"); if (lines.length >= 2) { String[] headers = lines[0].split("\\|"); String[] values = lines[1].split("\\|"); int minLength = Math.min(headers.length, values.length); for (int i = 0; i < minLength; i++) { dataMap.put(headers[i], values[i]); } } return dataMap; } //判断是不是json public boolean isPipeSeparatedData(String inputData) { return inputData.contains("|"); } // 比较和校验数据 public List<ValidationResult> compareAndValidate(String fileContent, JsonNode jsonConfig) { List<ValidationResult> results = new ArrayList<>(); Map<String, String> pipeDataMap = objectMapper.convertValue(jsonConfig, Map.class); // 统一转换为小写 fileContent = fileContent.replaceAll("\\s+", "").toLowerCase(); for (Map.Entry<String, String> entry : pipeDataMap.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); if (!value.isEmpty()) { value = value.replaceAll("\\s+", "").toLowerCase(); boolean found = fileContent.contains(value); results.add(new ValidationResult( "FIELD", key, value, found ? "Found" : "Not Found", found )); } } return results; } } 有发送了几个请求, 回馈信息不准确。已经存在的, 也会报错不存在。 我的后端"filE_CONTENT": "PALLET_ID|KNBOXNO|CARRIER|COC|CTRY|HAWB|PO|ORIGIN|INVOICENO|CARTONS|SHIPID|SHIP_DATE|TEL|SSCC|RETURN_TO1|RETURN_TO2|RETURN_TO3|RETURN_TO4|RETURN_TO5|RETURN_TO6|RETURN_TO7|RETURN_TO8|SHIP_TO1|SHIP_TO2|SHIP_TO3|SHIP_TO4|SHIP_TO5|SHIP_TO6|SHIP_TO7|SHIP_TO8|LINEITEM1|MPN1|QTY1|LINEITEM2|MPN2|QTY2|LINEITEM3|MPN3|QTY3|\nFO2501000233P0002||DGF-AD|NL|NL|8VG8286|0638138589|PVG|8VG8286|61/84|73292885370002|06/01/2025|00000000|001959499064098506|ADI EMEIA Logistics|Inbound Department|||||||PEGATRON CORPORATION|c/o DP World Logistics Netherlands BV|Van Hilststraat 23|5145 RK Waalwijk,Netherlands|5145 RK Waalwijk Netherlands||||00010|MLPF3AA/A|10|" 拿这个值跟我的文件内容或者图片内容比较 也没有问题啊 用json也没问题 为什么前段测试 会有问题
最新发布
07-18
### 验证正则表达式的匹配情况 为了测试给定的正则表达式 `**/src/**|src/**|**/*.java|**/*.sql|****/*.*` 是否能够正确匹配某些字符串,可以使用 Java 提供的 `Pattern` 和 `Matcher` 类。以下是实现这一功能的具体方法: #### 使用 Pattern 和 Matcher 测试正则表达式 通过调用 `Pattern.compile()` 方法编译正则表达式,并利用 `Matcher.matches()` 或其他相关方法来检测目标字符串是否符合该模式。 需要注意的是,在 Java 中,反斜杠 `\` 是转义字符,因此在定义正则表达式时需要将其加倍写成 `\\`[^1]。对于当前给出的正则表达式,可能还需要进一步调整以适应 Java 的语法需求。 下面是完整的代码示例: ```java import java.util.regex.Pattern; import java.util.regex.Matcher; public class TestRegex { public static void main(String[] args) { // 定义待测试的正则表达式 String regex = "**/src/**|src/**|**/*.java|**/*.sql|****/*.*"; // 转义特殊字符使其适配 Java 正则表达式语法规则 String escapedRegex = regex.replaceAll("\\*", "\\\\E\\\\*\\\\Q").replaceAll("/", "\\/"); escapedRegex = "\\Q" + escapedRegex + "\\E"; // 编译正则表达式 Pattern pattern = Pattern.compile(escapedRegex); // 待测试的目标字符串数组 String[] testStrings = { "/project/src/main.java", "src/test.sql", "file.txt", "data.csv" }; // 输出每条字符串的匹配结果 for (String str : testStrings) { Matcher matcher = pattern.matcher(str); if (matcher.matches()) { System.out.println("字符串 \"" + str + "\" 匹配成功!"); } else { System.out.println("字符串 \"" + str + "\" 不匹配!"); } } } } ``` 上述代码中,我们首先对原始正则表达式中的通配符进行了处理以便于其能在 Java 环境下正常工作。接着创建了一个包含多个文件路径样例的数组用于逐一检验它们是否满足指定条件[^3]。 #### 关键点解析 - **转义机制**: 在构建最终使用的正则串之前,需确保所有具有特殊含义但在此处作为普通文字对待的部分都被妥善转义。 - **matches 方法应用**: 这一函数会尝试让整个输入序列完全吻合所提供的模式描述;如果仅希望查找部分子串,则可考虑采用 find() 函数替代之[^2]。 --- ### 问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值