猿问

我如何用正则表达式替换这个函数

我有一个格式为 yy_MM_someRandomString_originalFileName 的文件名。


例子:


02_01_fEa3129E_my Pic.png

我想将前 2 个下划线替换为,/以便示例变为:


02/01/fEa3129E_my Pic.png

这可以用 replaceAll 来完成,但问题是文件也可能包含下划线。


@Test

void test() {


    final var input = "02_01_fEa3129E_my Pic.png";


    final var formatted = replaceNMatches(input, "_", "/", 2);


    assertEquals("02/01/fEa3129E_my Pic.png", formatted);

}


private String replaceNMatches(String input, String regex,

                               String replacement, int numberOfTimes) {

    for (int i = 0; i < numberOfTimes; i++) {

        input = input.replaceFirst(regex, replacement);

    }

    return input;

}

我使用循环解决了这个问题,但是有没有纯正则表达式的方法来做到这一点?


编辑:这种方式应该能够让我更改参数并将下划线的数量从 2 增加到 n。


炎炎设计
浏览 216回答 2
2回答

慕娘9325324

您可以使用 2 个捕获组并在替换中使用它们,其中匹配项_将被替换为/^([^_]+)_([^_]+)_用。。。来代替:$1/$2/正则表达式演示|&nbsp;Java演示例如:String regex = "^([^_]+)_([^_]+)_";String string = "02_01_fEa3129E_my Pic.png";String subst = "$1/$2/";Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(string);String result = matcher.replaceFirst(subst);System.out.println(result);结果02/01/fEa3129E_my Pic.png

阿晨1998

您当前的解决方案几乎没有问题:这是低效的——因为每个都replaceFirst需要从字符串的开头开始,所以它需要多次迭代相同的起始字符。它有一个错误- 因为第 1 点。当从开始而不是最后修改的地方迭代时,我们可以替换之前插入的值。例如,如果我们想两次替换单个字符,每次都用Xlike abc->XXc在代码 like 之后String input = "abc";input = input.replaceFirst(".", "X"); // replaces a with X -> Xbcinput = input.replaceFirst(".", "X"); // replaces X with X -> XbcXbc我们将以instead of结尾XXc,因为第二个replaceFirst将替换为Xwith Xinstead of bwith X。为避免此类问题,您可以重写代码以使用Matcher#appendReplacement和Matcher#appendTail方法,以确保我们将迭代输入一次并可以用我们想要的值替换每个匹配的部分private static String replaceNMatches(String input, String regex,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;String replacement, int numberOfTimes) {&nbsp; &nbsp; Matcher m = Pattern.compile(regex).matcher(input);&nbsp; &nbsp; StringBuilder sb = new StringBuilder();&nbsp; &nbsp; int i = 0;&nbsp; &nbsp; while(i++ < numberOfTimes && m.find() ){&nbsp; &nbsp; &nbsp; &nbsp; m.appendReplacement(sb, replacement); // replaces currently matched part with replacement,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // and writes replaced version to StringBuilder&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // along with text before the match&nbsp; &nbsp; }&nbsp; &nbsp; m.appendTail(sb); //lets add to builder text after last match&nbsp; &nbsp; return sb.toString();}使用示例:System.out.println(replaceNMatches("abcdefgh", "[efgh]", "X", 2)); //abcdXXgh
随时随地看视频慕课网APP

相关分类

Java
我要回答