String.replaceFirst无效

本文介绍在使用Java的replaceFirst方法时如何正确处理字符串中的特殊字符,特别是正则表达式中的‘+’号。通过实例演示了不进行转义导致的替换失败问题及解决方法。

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

replaceFirst(String regex, String replacement)

如果regex参数中有‘正则中的特殊符号‘,如我遇到的就是‘+’,那么该方法有可能失败,因为这些符号作为条件而不是内容去匹配了。

解决方法是对这些特殊符号进行转义。举个例子:

String img = "<img src=\"000\" ><img data-src=\"111\" width=\"\" src=\"222\"> xxx <img src=\"000\" > xxx <img data-src=\"3+33\" width=\"\" src=\"44+44\">";
		img = img.replaceFirst("44+44", "333");
    	System.out.println(img);
    	
    	img = img.replaceFirst("44+44".replace("+", "\\+"), "333");
    	System.out.println(img);

输出如下:

<img src="000" ><img data-src="111" width="" src="222"> xxx <img src="000" > xxx <img data-src="3+33" width="" src="44+44">
<img src="000" ><img data-src="111" width="" src="222"> xxx <img src="000" > xxx <img data-src="3+33" width="" src="333">

这里,第一次替换失败了,内容没有变化。

第二次先对'+'进行了转义,成功!

private Flux<String> requestLLMStream(String requestStr,PromptBo promptBo,MkPromptsBo question,MkPromptsBo answer,MkPromptsBo think,String url){ HttpClient client = HttpClient.newHttpClient(); HttpRequest request; try { request = HttpRequest.newBuilder() .uri(new URI(url)) .header(“Content-Type”, “application/json”) .POST(HttpRequest.BodyPublishers.ofString(requestStr)) .build(); } catch (Exception e) { return Flux.create(sink -> { sink.next(“{"status": "ERROR","error_msg": "构建大模型请求出现错误!"}”); sink.complete(); }); } return Flux.create(sink -> { CompletableFuture<HttpResponse<InputStream>> responseFuture = client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream()); responseFuture .completeOnTimeout(null, 60, TimeUnit.SECONDS) // 60秒超时 .thenAccept(response -> { if (response == null) { sink.next("{\"status\": \"ERROR\",\"error_msg\": \"请求超时\"}"); sink.complete(); return; } int code = response.statusCode(); if (code != 200) { sink.next("{\"status\": \"ERROR\",\"error_msg\": \"请求出现问题,请联系管理员!状态码:"+code+"\"}"); sink.complete(); return; } String idMessage = String.format("{\"type\":\"ids\",\"questionId\":\"%s\",\"answerId\":\"%s\"}\n\n", question.getId(), answer.getId()); sink.next(idMessage); AtomicBoolean isClientDisconnected = new AtomicBoolean(false); sink.onCancel(() -> { isClientDisconnected.set(true); }); try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.body(), StandardCharsets.UTF_8))) { String line; StringBuilder output = new StringBuilder(); StringBuilder thinkString = new StringBuilder(); ObjectMapper mapper2 = new ObjectMapper(); HashMap<String,String> processedLines = new HashMap<>(); // 用于记录"model" while ((line = reader.readLine()) != null && !isClientDisconnected.get()) { if(!line.isBlank()){ line = line.replaceFirst("data:",""); if ("[DONE]".equals(line.trim())) { break; } processJsonLine(processedLines,line, output, thinkString,mapper2); } sink.next(line); } // 完整答案拼接完成后,一次性入库 String fullAnswer = output.toString(); answer.setContent(fullAnswer); answer.setModelType(processedLines.get("model")); if(processedLines.containsKey("page_range")&&!processedLines.get("page_range").equals("null")){ answer.setPageRange(processedLines.get("page_range")); } if(promptBo.getModel().equals("deepseek-r1")||promptBo.getModel().equals("deepseek-r1-volc")) { think.setContent(thinkString.toString()); think.setModelType(processedLines.get("model")); think.setPageRange(processedLines.get("page_range")); promptsService.updateByBo(think); } question.setModelType(processedLines.get("model")); promptsService.updateByBo(answer); promptsService.updateByBo(question); if (!isClientDisconnected.get()) { // 如果客户端没有断开连接,发送 [DONE] 信号 sink.next("[DONE]"); } sink.complete(); } catch (Exception e) { sink.error(new RuntimeException("{\"status\": \"ERROR\",\"error_msg\": \"处理响应时发生错误:"+e+"\"}")); } }) .exceptionally(e -> { if (e instanceof IOException) { sink.next("{\"status\": \"ERROR\",\"error_msg\": \"模型调用请求失败:"+ e.getMessage()+"\"}"); } else if (e instanceof InterruptedException) { sink.next("{\"status\": \"ERROR\",\"error_msg\": \"请求模型连接被中断\"}"); } else { sink.next("{\"status\": \"ERROR\",\"error_msg\": \"发生未知错误:"+ e.getMessage()+"\"}"); } sink.complete(); return null; }); }); } private R<String> getFileContent(String fileType,MkFiles file) throws Exception { String content; if(fileType.equals(“pdf”)||fileType.equals(“png”)||fileType.equals(“jpg”)||fileType.equals(“jpeg”)||fileType.equals(“gif”)){ if (file.getTargetPath() == null || file.getTargetPath().isEmpty()){ return R.fail(“文件存在”); } R<String> r = documentService.getTransferDocumentContent(file.getTargetPath()); if (r.getCode() == R.FAIL){ return R.fail(“文件转换内容存在”); } content = r.getMsg(); }else if (fileType.equals("html")||fileType.equals("htm")){ content = documentService.getHtmlDoc(file.getSourcePath()); }else if(fileType.equals("docx")|| fileType.equals("doc")|| fileType.equals("xls")|| fileType.equals("xlsx")|| fileType.equals("wps")||fileType.equals("json")){ content = extractFileContent(file.getSourcePath()); } else{ return R.fail("文件类型支持"); } return R.ok("",content); }
05-15
好的,我来逐个回答你的问题。 首先,针对你的问题,我可以用 Java 语言编写一个控制台程序,实现文本的查找替换和单词统计功能。具体代码如下: ```java import java.util.Scanner; public class TextProcessor { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // 读入源字符串 System.out.print("请输入源字符串:"); String source = scanner.nextLine(); // 读入要查找的字符串和替换的字符串 System.out.print("请输入要查找的字符串:"); String find = scanner.nextLine(); System.out.print("请输入要替换的字符串:"); String dest = scanner.nextLine(); // 选项菜单 while (true) { System.out.println("请选择要进行的操作:"); System.out.println("1. 将源字符串中的第一个 " + find + " 替换为 " + dest); System.out.println("2. 将源字符串中的最后一个 " + find + " 替换为 " + dest); System.out.println("3. 将源字符串中所有的 " + find + " 替换为 " + dest); System.out.println("4. 统计源字符串中的单词数"); System.out.println("5. 退出程序"); int choice = scanner.nextInt(); scanner.nextLine(); // 读取多余的回车符 switch (choice) { case 1: String replaced1 = replaceFirst(source, find, dest); System.out.println("替换后的字符串为:" + replaced1); break; case 2: String replaced2 = replaceLast(source, find, dest); System.out.println("替换后的字符串为:" + replaced2); break; case 3: String replaced3 = replaceAll(source, find, dest); System.out.println("替换后的字符串为:" + replaced3); break; case 4: int wordCount = countWords(source); System.out.println("源字符串中的单词数为:" + wordCount); break; case 5: System.out.println("程序已退出。"); return; default: System.out.println("无效的选择,请重新输入。"); break; } } } // 替换源字符串中的第一个 find 为 dest public static String replaceFirst(String source, String find, String dest) { int index = source.indexOf(find); if (index == -1) { return source; } return source.substring(0, index) + dest + source.substring(index + find.length()); } // 替换源字符串中的最后一个 find 为 dest public static String replaceLast(String source, String find, String dest) { int index = source.lastIndexOf(find); if (index == -1) { return source; } return source.substring(0, index) + dest + source.substring(index + find.length()); } // 替换源字符串中所有的 find 为 dest public static String replaceAll(String source, String find, String dest) { return source.replaceAll(find, dest); } // 统计源字符串中的单词数 public static int countWords(String source) { String[] words = source.split("\\W+"); return words.length; } } ``` 这个程序有一个选项菜单,可以让用户选择要进行的操作。输入源字符串、要查找的字符串和要替换的字符串后,用户可以选择将源字符串中的第一个字符串 find 替换为 dest,或者将最后一个字符串 find 替换为 dest,或者将所有的字符串 find 替换为 dest,或者统计源字符串中的单词数,或者退出程序。 其中,替换操作使用了 String 类的 replaceFirst、lastIndexOf 和 replaceAll 方法,单词统计操作使用了 String 类的 split 方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值