Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用正则表达式用修改过的字符替换字符串中的序列_Java_Regex_String_Replace - Fatal编程技术网

Java 使用正则表达式用修改过的字符替换字符串中的序列

Java 使用正则表达式用修改过的字符替换字符串中的序列,java,regex,string,replace,Java,Regex,String,Replace,我正在尝试使用正则表达式解决一个问题,无论它是否在网站上工作 到目前为止,我有以下代码,它没有在两个连续的相等字符之间添加*。相反,它只是推平它们,并用一组字符串替换它们 public String pairStar(String str) { Pattern pattern = Pattern.compile("([a-z])\\1", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(str);

我正在尝试使用正则表达式解决一个问题,无论它是否在网站上工作

到目前为止,我有以下代码,它没有在两个连续的相等字符之间添加
*
。相反,它只是推平它们,并用一组字符串替换它们

public String pairStar(String str) {
    Pattern pattern = Pattern.compile("([a-z])\\1", Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(str);
    if(matcher.find())
    matcher.replaceAll(str);//this is where I don't know what to do
    return str;
}

我想知道如何继续使用regex并替换整个字符串。如果需要的话,我认为递归系统会有所帮助。

我不懂java,但我相信java中有字符串替换函数或正则表达式替换函数。您的匹配字符串将是

([a-z])\\1
替换字符串是

$1*$1
经过一番搜索我想你是在找这个

str.replaceAll("([a-z])\\1", "$1*$1").replaceAll("([a-z])\\1", "$1*$1");
这项工作:

while(str.matches(".*(.)\\1.*")) {
    str = str.replaceAll("(.)\\1", "$1*$1");
}
return str;
正则表达式的解释: 搜索正则表达式
(.)\\1

  • ()
    表示“任何字符”(括号中的
    ),括号中创建一个组-第1组(左第一个括号)
  • \\1
    ,在正则表达式中是
    \1
    (java文字
    字符串必须用另一个反斜杠转义反斜杠)表示“第一组”-这种术语称为“反引用”
因此,
()\1
一起表示“任何重复字符”


替换正则表达式
$1*$1

  • $1
    术语表示“作为组1捕获的内容”

递归解决方案: 从技术上讲,该站点上要求的解决方案是递归解决方案,因此这里是递归实现:

public String pairStar(String str) {
    if (!str.matches(".*(.)\\1.*")) return str;
    return pairStar(str.replaceAll("(.)\\1", "$1*$1"));
}

FWIW,这里有一个非递归解决方案:

public String pairStar(String str) {
  int len = str.length();
  StringBuilder sb = new StringBuilder(len*2);
  char last = '\0';
  for (int i=0; i < len; ++i) {
    char c = str.charAt(i);
    if (c == last) sb.append('*');
    sb.append(c);
    last = c;
  }
  return sb.toString();
}
publicstringpairstar(stringstr){
int len=str.length();
StringBuilder sb=新StringBuilder(len*2);
char last='\0';
对于(int i=0;i
这是我自己的解决方案

递归解决方案(这可能或多或少就是问题设计的解决方案)

两种解决方案具有相同的精神。它们都检查当前字符是否与下一个字符相同。如果它们相同,则在两个相同字符之间插入一个
*
。然后我们继续检查下一个字符。这是从输入
aaaa
生成预期输出
a*a*a

“(..\\1”
的常规正则表达式解决方案有一个问题:它每匹配一个字符消耗2个字符。因此,我们无法比较第二个字符后面的字符是否是同一个字符。前瞻用于解决此问题-它将与下一个角色进行比较,而不使用它


这与递归解决方案类似,我们比较下一个字符
str.charAt(0)=str.charAt(1)
,同时在子字符串上递归调用函数,只删除当前字符
pairStar(str.substring(1)

,那么星号(*)在哪里在您的正则表达式中?如果只是查找两个连续相等字符的实例,我需要一个吗?目标:将(char)(samechar)变成(char)*(samechar)当你找到两个相等的字符时,你需要添加“*”。FWIW,反向引用很昂贵。我只是使用了一个StringBuilder并扫描了输入。哦,顺便说一句,codingbat问题并没有说什么不区分大小写。是的,我只是在那个网站上做了大约六个拼图。它们都不需要,甚至没有从recu中受益rsion。不过,这个解决方案是错误的。给定
aaaa
,您应该返回
a*a*a
@nhahtdh
str.replaceAll(([a-z])\\1“,“$1*$1”)。replaceAll([a-z])\\1“,“$1*$1”);
应该始终有效。:)正确-它通过了codingbat上的测试用例。实际上,有一种方法可以用单个正则表达式(没有循环,没有递归,只有一个
replaceAll
)来解决这个问题。但我反对浪费很多时间去找正则表达式。找一个好的正则表达式需要时间,而你可以在10分钟内用一种简单的方式来做,这只是浪费时间。不过这要看情况而定。起初我使用递归——后来当我学习高级正则表达式时,我可以很快地编写它。这不是一个非常实际的问题,因此我认为这是一个挑战,即某种形式的解决方案是否可行。
public String pairStar(String str) {
    if (str.length() <= 1) return str;
    else return str.charAt(0) +
                (str.charAt(0) == str.charAt(1) ? "*" : "") +
                pairStar(str.substring(1));
}
public String pairStar(String str) {
  return str.replaceAll("(.)(?=\\1)", "$1*");
}