我必须将一个数字及其本身匹配 14 次。然后我在 regexstor.net/tester 中找到了以下正则表达式:
(\d)\1{14}
编辑
当我将其粘贴到我的代码中时,正确包含反斜杠:
"(\\d)\\1{14}"
我已将反向引用
"\1"
替换为 "$1"
,用于替换 Java 中的匹配项。
然后我意识到这是行不通的。当您需要在 REGEX 中反向引用匹配项时,在 Java 中,您必须使用
"\N"
,但是当您想要替换它时,运算符是 "$N"
。
我的问题是:为什么?
$1
不是 Java 正则表达式中的反向引用,也不是我能想到的任何其他风格。仅当您更换某物时才使用
$1
:
String input="A12.3 bla bla my input";
input = StringUtils.replacePattern(
input, "^([A-Z]\\d{2}\\.\\d).*$", "$1");
// ^^^^
关于什么是反向引用存在一些错误信息,包括我从中获取该片段的地方:具有反向引用的简单 java 正则表达式不起作用。
Java 按照其他现有风格建模其正则表达式语法,其中
$
已经是元字符。它锚定到字符串的末尾(或多行模式下的行)。
类似地,Java 使用
\1
进行反向引用。因为正则表达式是字符串,所以必须对其进行转义:\\1
。
从词汇/句法的角度来看,
$1
确实可以明确使用(作为奖励,它可以防止在使用反向引用时需要“邪恶的转义”)。
要匹配行尾之后的
1
,正则表达式需要为 $\n1
:
this line
1
使用熟悉的语法而不是更改规则更有意义,其中大部分规则来自 Perl。
Perl 的第一个版本于 1987 推出,比 Java 早得多,Java 于 1995 发布测试版。
我翻出了 Perl 1 的手册页,上面写着:
也可以使用括号结构
(\ ...\ )
,在这种情况下\<digit>
匹配第digit
' 个子字符串。 (在模式之外,始终在数字前面使用$
而不是\
。$<digit>
(以及$\`
、$&
和$'
)的范围延伸到封闭 BLOCK 的末尾或 eval 字符串,或与子表达式的下一个模式匹配。\<digit>
表示法有时在当前模式之外起作用,但不应依赖。)您可以有任意数量的括号。如果子字符串超过 9 个,则变量$10
、$11
、... 引用相应的子字符串。在该模式中,如果反向引用之前至少有那么多左括号,则\10
、\11
等将引用回子字符串。否则(为了向后兼容)\10
与\010
(退格键)相同,\11
与\011
(制表符)相同。等等。 (\1
到\9
始终是反向引用。)
\1
完美配合。您的问题更可能是 Java 中正则表达式模式的“整体”转义。
如果你想要图案
(\d)\1{14}
传递给正则表达式引擎,您首先需要对其进行转义,因为当您编写它时它是一个java字符串:
(\\d)\\1{14}
Voila,工作起来就像一个魅力:goo.gl/BNCx7B(添加http://,所以不允许网址缩短器,但tutorialspoint.com似乎没有其他选择)
离线示例:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HelloWorld{
public static void main(String []args){
String test = "555555555555555"; // 5 followed by 5 for 14 times.
String pattern = "(\\d)\\1{14}";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(test);
if (m.find( )) {
System.out.println("Matched!");
}else{
System.out.println("not matched :-(");
}
}
}
Regex代码来匹配重复项并修剪字符串中的相邻字符。
例如:这可以用来修复单词中偶尔出现的拼写错误。
String text = "aabbbccccdddddefg";
System.out.println(text.replaceAll("(.)\1*(?=\\1)", ""));
// Outputs: abcdefg
感谢 dognose 的回答,提醒我们在 Lookarounds (?=)
中调用 backreference
字符时,需要在 Java 中对其进行转义才能正常运行。