Java 中的正则表达式反向引用

问题描述 投票:0回答:3

我必须将一个数字及其本身匹配 14 次。然后我在 regexstor.net/tester 中找到了以下正则表达式:

(\d)\1{14}

编辑

当我将其粘贴到我的代码中时,正确包含反斜杠:

"(\\d)\\1{14}"

我已将反向引用

"\1"
替换为
"$1"
,用于替换 Java 中的匹配项。

然后我意识到这是行不通的。当您需要在 REGEX 中反向引用匹配项时,在 Java 中,您必须使用

"\N"
,但是当您想要替换它时,运算符是
"$N"

我的问题是:为什么?

java regex
3个回答
10
投票

$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
 始终是反向引用。)


4
投票
我认为主要问题不是反向引用 - 它与 java 中的

\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 :-("); } } }
    

0
投票
我使用下面的

Regex代码来匹配重复项并修剪字符串中的相邻字符。

例如:这可以用来修复单词中偶尔出现的拼写错误。

String text = "aabbbccccdddddefg"; System.out.println(text.replaceAll("(.)\1*(?=\\1)", "")); // Outputs: abcdefg
感谢 

dognose 的回答,提醒我们在 Lookarounds (?=) 中调用 backreference

 字符时,需要在 Java 中对其进行转义才能正常运行。

© www.soinside.com 2019 - 2024. All rights reserved.