You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用Scanner.useDelimiter仅读取run()内的指定内容?

原代码问题

你写的分隔符逻辑存在三个硬伤,根本没法实现提取run()括号内容的需求:

  • 分隔符规则run\\W匹配范围不可控:\W代表任意非单词字符,除了(之外,run后面跟的空格、标点、特殊符号都会被识别为分隔符的一部分,很容易出现误匹配。
  • 就算把分隔符改成精确匹配run\\(,也只能把run(作为内容分割边界,后续读取到的内容会带上右括号以及run()块后面的其他文本,没法精准截出括号内部的内容。
  • Scanner的分隔符机制本身就不适合做定向内容提取:当输入以run(开头时,开头的run(会被识别为前置分隔符直接跳过,再叠加你没有处理右边界的逻辑,自然读不到有效内容。
实现方案

别折腾Scanner分隔符了,直接用正则捕获或者字符串边界匹配的方式提取内容,不管输入是不是以run(开头、run()在输入的什么位置都能正常识别。

普通场景(括号内无嵌套括号)

用正则非贪婪匹配直接捕获括号内的内容,代码最简单:

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExtractRunParam {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 读取整行输入,需要读取多行输入的话可以改成sc.useDelimiter("\\A")再调用sc.next()
        String input = sc.nextLine();
        sc.close();

        // 匹配规则:定位run(...)片段,用捕获组拿括号里的内容
        Pattern runPattern = Pattern.compile("run\\((.*?)\\)");
        Matcher matcher = runPattern.matcher(input);

        if (matcher.find()) {
            String innerContent = matcher.group(1);
            // 需要去掉内容首尾空格的话,在这里调用innerContent.trim()即可
            System.out.println(innerContent);
        } else {
            System.out.println("未识别到符合格式的run(...)片段");
        }
    }
}

测试效果:

  • 输入前置内容run(测试内容123)后置内容,输出测试内容123
  • 输入run(直接以run开头的输入),输出直接以run开头的输入
  • 输入run( 内容前后带空格 ),输出内容前后带空格

复杂场景(括号内存在嵌套括号)

如果括号里可能出现多层括号嵌套(比如run(calc(1,2), print(3))这类内容),正则非贪婪匹配会提前匹配到第一个右括号导致内容截断,这时候用括号计数的方式找配对右括号更可靠:

import java.util.Scanner;

public class ExtractRunParamWithNest {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String input = sc.nextLine();
        sc.close();

        int runStartIdx = input.indexOf("run(");
        if (runStartIdx == -1) {
            System.out.println("未识别到符合格式的run(...)片段");
            return;
        }

        int leftBracketPos = runStartIdx + 4; // run(共4个字符,后面就是左括号的下一个位置
        int bracketLevel = 1;
        int rightBracketPos = -1;

        // 遍历找配对的右括号
        for (int i = leftBracketPos; i < input.length(); i++) {
            char current = input.charAt(i);
            if (current == '(') bracketLevel++;
            if (current == ')') bracketLevel--;
            if (bracketLevel == 0) {
                rightBracketPos = i;
                break;
            }
        }

        if (rightBracketPos == -1) {
            System.out.println("括号不配对,内容格式错误");
            return;
        }

        String innerContent = input.substring(leftBracketPos, rightBracketPos);
        System.out.println(innerContent);
    }
}

这个实现可以准确识别多层嵌套的括号边界,比如输入run(sum(1,2,max(3,4)), log("test")),可以完整提取括号内的sum(1,2,max(3,4)), log("test")内容。

补充说明
  • Scanner的useDelimiter只适合简单的固定分隔符切分场景,用来提取指定格式的结构化内容不仅逻辑绕,还很容易出边界问题,不如正则或者字符串遍历的方式可控。
  • 如果输入里存在多个run(...)片段,只要循环调用matcher.find()(正则方案)或者循环查找下一个run(的位置(计数方案),就能批量提取所有片段的括号内内容。

内容的提问来源于stack exchange,提问作者theworld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:21:22