Java 使用正则表达式替换子字符串

Java 使用正则表达式替换子字符串,java,Java,所以我一直在尝试制作这个简单的加密程序,但我似乎不知道一些事情。我需要输入的短语是 This is a very big morning. 当我输入它时,尽管它返回字符串 This is a ag',rery dug>?/ijeb..w ssadorninjeb..w 相反,我回来了 This is a ajedg>P/..w',rery dg>P/ijedg>P/..w ssadorninjedg>P/..w 我不明白为什么以及如何修复它?我已经学习java

所以我一直在尝试制作这个简单的加密程序,但我似乎不知道一些事情。我需要输入的短语是

This is a very big morning.
当我输入它时,尽管它返回字符串

This is a ag',rery dug>?/ijeb..w ssadorninjeb..w
相反,我回来了

This is a ajedg>P/..w',rery dg>P/ijedg>P/..w ssadorninjedg>P/..w
我不明白为什么以及如何修复它?我已经学习java大约一个月了,所以我还是新手,如果有类似的问题已经得到了回答,请将我链接到那里,我将删除这篇文章

代码如下:

import static java.lang.System.out;
import java.util.Scanner;
class Encryption {
    public static void main(String[] args) {
        Scanner userInput = new Scanner(System.in);
        Crypto user1 = new Crypto();
        out.print("Please enter in a sentence: ");
        String user = userInput.nextLine();
        user1.encrypt(user);
        out.print(user1.getEncrypt());
    }
}

public Crypto() { }
public String myEn;
public void encrypt(String Sentence) {
    myEn = Sentence.replaceAll("v","ag',r")
                   .replaceAll("m" , "ssad")
                   .replaceAll("g" , "jeb..w")
                   .replaceAll("b" , "dg>P/");
}

public String getEncrypt() {
        return myEn;
}
}

当您更换
g
时,其更换包含一个
b
,因此当您更换
b
时,您将从
g
更换中获得所有
b
。也适用于
v

你能做的就是

Sentence.replaceAll("g" , "jeb..w")
    .replaceFirst("b" , "dg>P/")     // as no g's before b's and only want to replace the first
    .replaceFirst("v","ag',r")
    .replaceFirst("m" , "ssad");
但这只适用于这一句话


你能做的是:

  • 创建要替换的所有角色的地图,然后进行替换
  • 创建要在原始字符串上替换的每个字符的索引列表
  • 颠倒列表的顺序(从高到低)
  • 从列表中的第一个索引(要替换的最后一个字符)开始,将该索引处的字符替换为映射中的替换字符
  • 重复4,沿管柱向后移动

  • 您获得不同输出的原因是,链式替换采用了先前替换的返回值。因此,在你的例子中,如果有一个
    v
    ,它将被
    ag',r
    改变,其中有一个
    g
    。然后,
    g
    将触发
    replaceAll(“g”,“jeb..w”)

    为避免发生这种情况,应更改替换的顺序:

    Sentence.replaceAll("g" , "jeb..w")
            .replaceAll("b" , "dg>P/")
            .replaceAll("v","ag',r")
            .replaceAll("m" , "ssad");
    

    但是,前两个replace语句无法修复,因为其中一个语句将
    b
    替换为包含
    g
    的字符串,反之亦然,因此您可能需要更改要替换的字符。

    首先,您应该使用
    replace()
    ,而不是
    replaceAll()
    。两者都替换找到的所有匹配项,但replaceAll()使用正则表达式进行匹配,replace()使用纯文本

    接下来,您的替换会互相妨碍,因此请使用StringBuffer,从第八个字符开始,然后向后一次替换一个字符


    解密同样应该从左边开始,一次只能使用一个字符。

    正如其他人已经告诉您的那样,问题是您在几次迭代(replaceAll调用)中替换字符,而不是一次。如果要防止替换用于替换其他字符的字符,可以使用
    Matcher
    类中的
    appendReplacement
    appendTail

    下面是你可以这样做的方法

    // We need to store somewhere info about original and its replacement
    // so we will use Map
    Map<String, String> replacements = new HashMap<>();
    replacements.put("v", "ag',r");
    replacements.put("m", "ssad");
    replacements.put("g", "jeb..w");
    replacements.put("b", "dg>P/");
    
    // we need to create pattern which will find characters we want to replace
    Pattern pattern = Pattern.compile("[vmgb]");//this will do 
    
    Matcher matcher = pattern.matcher("This is a very big morning.");
    
    StringBuffer sb = new StringBuffer();// this will be used to create
                                         // string with replaced characters
    
    // lets start replacing process
    while (matcher.find()) {//first we need to find our characters
    
        // then pick from map its replacement 
        String replacement = replacements.get(matcher.group());
        // and pass it to appendReplacement method
        matcher.appendReplacement(sb, replacement);
    
        // we repeat this process until original string has no more
        // characters to replace
    }
    //after all we need to append to StringBuffer part after last replacement
    matcher.appendTail(sb);
    
    System.out.println(sb);
    

    This is a ag',rery dg>P/ijeb..w ssadorninjeb..w.