Java 正则表达式匹配器跳过匹配项
Java Regex Matcher skipping the matches
下面是我的 Java 代码,用于删除所有匹配的相邻字母对,但是 Java 匹配器 class.
出现了一些问题
My Approach
我正在尝试查找输入中所有连续的重复字符,例如
aaa, bb, ccc, ddd
接下来用最后匹配的模式替换奇数长度匹配,用 ""
替换偶数长度匹配,即
aaa -> a
bb -> ""
ccc -> c
ddd -> d
s has single occurrence, so it's not matched by the regex pattern and excluded from the substitution
我正在调用 Matcher.appendReplacement
根据组长度(偶数或奇数)有条件地替换输入中匹配的模式。
Code:
public static void main(String[] args) {
String s = "aaabbcccddds";
int i=0;
StringBuffer output = new StringBuffer();
Pattern repeatedChars = Pattern.compile("([a-z])\1+");
Matcher m = repeatedChars.matcher(s);
while(m.find()) {
if(m.group(i).length()%2==0)
m.appendReplacement(output, "");
else
m.appendReplacement(output, "");
i++;
}
m.appendTail(output);
System.out.println(output);
}
输入:aaabbcccddds
实际输出:aaabbcccds
(仅将 ddd
替换为 d
,但跳过 aaa
、bb
和 ccc
)
预期输出:acds
你可以这样试试:
public static void main(String[] args) {
String s = "aaabbcccddds";
StringBuffer output = new StringBuffer();
Pattern repeatedChars = Pattern.compile("(\w)(\1+)");
Matcher m = repeatedChars.matcher(s);
while(m.find()) {
if(m.group(2).length()%2!=0)
m.appendReplacement(output, "");
else
m.appendReplacement(output, "");
}
m.appendTail(output);
System.out.println(output);
}
和你的类似,但是当只得到第一组时,你匹配第一个字符,你的长度总是0。这就是为什么我引入第二组,即匹配的相邻字符。因为它的长度为 -1,所以我反转了奇偶逻辑,瞧 -
acds
已打印。
您不需要多个 if 语句。尝试:
(?:(\w)(?:\1\1)+|(\w)\2+)(?!\1|\2)
替换为</code></p>
<p><a href="https://regex101.com/r/L7Ga3Y/1" rel="nofollow noreferrer">Regex live demo</a></p>
<p>Java代码:</p>
<pre><code>str.replaceAll("(?:(\w)(?:\1\1)+|(\w)\2+)(?!\1|\2)", "");
正则表达式细分:
(?:
非捕获组开始
(\w)
抓取一个单词字符
(?:\1\1)+
匹配偶数个相同字符
|
或
(\w)
抓取一个单词字符
\2+
匹配任意数量的相同字符
)
非捕获组结束
(?!\1|\2)
后面没有前面捕获的字符
将 Pattern
和 Matcher
与 StringBuffer
一起使用:
StringBuffer output = new StringBuffer();
Pattern repeatedChars = Pattern.compile("(?:(\w)(?:\1\1)+|(\w)\2+)(?!\1|\2)");
Matcher m = repeatedChars.matcher(s);
while(m.find()) m.appendReplacement(output, "");
m.appendTail(output);
System.out.println(output);
这可以在单个 replaceAll
调用中完成,如下所示:
String repl = str.replaceAll( "(?:(.)\1)+", "" );
正则表达式 (?:(.)\1)+
匹配所有出现的偶数重复并将其替换为空字符串,这使我们得到奇数重复的第一个字符。
代码使用 Pattern
和 Matcher
:
final Pattern p = Pattern.compile( "(?:(.)\1)+" );
Matcher m = p.matcher( "aaabbcccddds" );
String repl = m.replaceAll( "" );
//=> acds
下面是我的 Java 代码,用于删除所有匹配的相邻字母对,但是 Java 匹配器 class.
出现了一些问题My Approach
我正在尝试查找输入中所有连续的重复字符,例如
aaa, bb, ccc, ddd
接下来用最后匹配的模式替换奇数长度匹配,用 ""
替换偶数长度匹配,即
aaa -> a
bb -> ""
ccc -> c
ddd -> d
s has single occurrence, so it's not matched by the regex pattern and excluded from the substitution
我正在调用 Matcher.appendReplacement
根据组长度(偶数或奇数)有条件地替换输入中匹配的模式。
Code:
public static void main(String[] args) {
String s = "aaabbcccddds";
int i=0;
StringBuffer output = new StringBuffer();
Pattern repeatedChars = Pattern.compile("([a-z])\1+");
Matcher m = repeatedChars.matcher(s);
while(m.find()) {
if(m.group(i).length()%2==0)
m.appendReplacement(output, "");
else
m.appendReplacement(output, "");
i++;
}
m.appendTail(output);
System.out.println(output);
}
输入:aaabbcccddds
实际输出:aaabbcccds
(仅将 ddd
替换为 d
,但跳过 aaa
、bb
和 ccc
)
预期输出:acds
你可以这样试试:
public static void main(String[] args) {
String s = "aaabbcccddds";
StringBuffer output = new StringBuffer();
Pattern repeatedChars = Pattern.compile("(\w)(\1+)");
Matcher m = repeatedChars.matcher(s);
while(m.find()) {
if(m.group(2).length()%2!=0)
m.appendReplacement(output, "");
else
m.appendReplacement(output, "");
}
m.appendTail(output);
System.out.println(output);
}
和你的类似,但是当只得到第一组时,你匹配第一个字符,你的长度总是0。这就是为什么我引入第二组,即匹配的相邻字符。因为它的长度为 -1,所以我反转了奇偶逻辑,瞧 -
acds
已打印。
您不需要多个 if 语句。尝试:
(?:(\w)(?:\1\1)+|(\w)\2+)(?!\1|\2)
替换为</code></p>
<p><a href="https://regex101.com/r/L7Ga3Y/1" rel="nofollow noreferrer">Regex live demo</a></p>
<p>Java代码:</p>
<pre><code>str.replaceAll("(?:(\w)(?:\1\1)+|(\w)\2+)(?!\1|\2)", "");
正则表达式细分:
(?:
非捕获组开始(\w)
抓取一个单词字符(?:\1\1)+
匹配偶数个相同字符|
或(\w)
抓取一个单词字符\2+
匹配任意数量的相同字符
)
非捕获组结束(?!\1|\2)
后面没有前面捕获的字符
将 Pattern
和 Matcher
与 StringBuffer
一起使用:
StringBuffer output = new StringBuffer();
Pattern repeatedChars = Pattern.compile("(?:(\w)(?:\1\1)+|(\w)\2+)(?!\1|\2)");
Matcher m = repeatedChars.matcher(s);
while(m.find()) m.appendReplacement(output, "");
m.appendTail(output);
System.out.println(output);
这可以在单个 replaceAll
调用中完成,如下所示:
String repl = str.replaceAll( "(?:(.)\1)+", "" );
正则表达式 (?:(.)\1)+
匹配所有出现的偶数重复并将其替换为空字符串,这使我们得到奇数重复的第一个字符。
代码使用 Pattern
和 Matcher
:
final Pattern p = Pattern.compile( "(?:(.)\1)+" );
Matcher m = p.matcher( "aaabbcccddds" );
String repl = m.replaceAll( "" );
//=> acds