当试图替换某些字符串时,Java代码会无限循环

当试图替换某些字符串时,Java代码会无限循环,java,regex,loops,Java,Regex,Loops,以下代码替换%%之间的字符串 String OrgStr = "Alarm for %Received Number% has arrived %test% is ok. Please visit %Received Number%"; String rcNumber = "1234567"; int firstPer, secPer; do { firstPer = OrgStr.indexOf('%'); //position of first % secPer = Org

以下代码替换%%之间的字符串

String OrgStr = "Alarm for %Received Number% has arrived %test% is ok. Please visit %Received Number%";
String rcNumber = "1234567";

int firstPer, secPer;
do
{
    firstPer = OrgStr.indexOf('%'); //position of first %
    secPer = OrgStr.indexOf('%', firstPer+1); //position of second %

    //extract the string in between first % and second %
    String toBeReplac = OrgStr.substring(firstPer, secPer+1);

    //The replaced string
    //if (toBeReplac.equals("%Received Number%"))// if i put this if condition then code goes to infinite loop
        OrgStr=OrgStr.substring(0, firstPer)+ rcNumber +OrgStr.substring((secPer+1),OrgStr.length());

    firstPer = OrgStr.indexOf('%', firstPer+1);
}while(firstPer>0);

System.out.println(OrgStr);
正如我在上面的代码中提到的,当我将行
if(tobereplace.equals(“%receivedname%”)放入
时,代码进入无限循环。我只想在%之间的字符串是接收号码时进行替换。

请尝试以下操作:

      String Str = "Alarm for %Received Number% has arrived %test% is ok. Please visit %Received Number%";
      System.out.println(Str.replaceAll("%Received Number%","Java"));
输出:

         Alarm for AMROOD has arrived %test% is ok. Please visit AMROOD

基本上,问题是在每次迭代时重新初始化firstPer的值:

firstPer = OrgStr.indexOf('%');
firstPer始终具有第一次出现的“%”的值,这就是为什么有一个无止境的循环

因此,您需要向该调用添加第二个参数,以确保更新firstPer的值,或在其他地方初始化firstPer一次,并正确更新其值

编辑

为了澄清,你只需要把句子删掉

firstPer = OrgStr.indexOf('%');
并将其粘贴到之前执行。然后,您将获得以下输出:

1234567的警报已到达%test%正常。请访问1234567

我想这就是您要查找的输出。

正确的代码可以:

firstPer = OrgStr.indexOf('%'); //position of first %
secPer = OrgStr.indexOf('%', firstPer+1); //position of second %
if (firstPer == -1 || secPer == 0) {
    break;
}
(或反转条件并将循环的其余部分放置在if内。)

我们最好使用更高效的模式替换和StringBuffer

public String eval(String s) {
    StringBuffer sb = new StringBuffer();
    Pattern variablePattern = Pattern.compile("%([\\w ]{0,20})%");
    Matcher matcher = variablePattern.matcher(s);
    while (matcher.find()) {
        String variable = matcher.group(1);
        String value = matcher.group(0);
        switch (variable) {
            case "":
                value = "%"; // "%%" becomes a single "%" (self-escaped.
                break;
            case "Received Number":
                value = "123456";
                break;
            case "test":
                value = "...";
                break;
            default:
                throw new IllegalArgumentException("No such variable: " + variable);
        }
        matcher.appendReplacement(sb, value);
    }
    matcher.appendTail(sb);
    return sb.toString();
}
在这里,我认为变量名只包含单词字符或空格,最多20个字符。这将有助于文本中的唯一百分比。百分比可能由变量“%%”实现

如果在将名称映射到值中维护变量,则不需要switch语句

public String eval(String s, Map<String, String> variables) {

}
publicstringeval(字符串、映射变量){
}

我会想象if语句失败了,而您没有执行子字符串,因此索引位置永远不会改变猜测当字符串中只剩下一个
%
时会发生什么。听说过
string.format
吗?使用适当的正则表达式来执行此操作,它的字符串更简单。替换(“%Received Number%”),替换字符串);我不能使用replace和replaceALL函数。