了解这个正则表达式

问题描述:

我想了解下面的内容。了解这个正则表达式

^([^=]+)(?:(?:\\=)(.+))?$ 

任何想法?

这是在这里使用。显然它是命令行解析器,但我试图理解语法,所以我实际上可以运行该程序。这是从commandline-jmxclient,他们没有设置JMX属性的文件,但在他们的源代码中,有这样的选项,所以我只想了解我可以如何调用该方法。

Matcher m = Client.CMD_LINE_ARGS_PATTERN.matcher(command); 
    if ((m == null) || (!m.matches())) { 
    throw new ParseException("Failed parse of " + command, 0); 
    } 

    this.cmd = m.group(1); 
    if ((m.group(2) != null) && (m.group(2).length() > 0)) 
    this.args = m.group(2).split(","); 
    else 
    this.args = null; 
+0

两个最佳答案都是正确的(Dmitry's和FailedDev's)。应该指出的是,这个正则表达式可以简化为 –

好解释读了会是这样:

" 
^   # Assert position at the beginning of the string 
(   # Match the regular expression below and capture its match into backreference number 1 
    [^=]  # Match any character that is NOT a “=” 
     +   # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
) 
(?:   # Match the regular expression below 
    (?:   # Match the regular expression below 
     =   # Match the character “=” literally 
    ) 
    (   # Match the regular expression below and capture its match into backreference number 2 
     .   # Match any single character that is not a line break character 
     +   # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
    ) 
)?   # Between zero and one times, as many times as possible, giving back as needed (greedy) 
$   # Assert position at the end of the string (or before the line break at the end of the string, if any) 
" 

将捕捉一切=以引用1和之前的一切后它backrefrence 2.

例如

33333098320498 
adhajdh =3232-40923-04924-0924 

对于第一个字符串,一切都被捕获到$ 1。

对于第二个:

adhajdh <---------- captured to $1 
3232-40923-04924-0924 <----- captured to $2 
+0

我真的不认为那些带注释的正则表达式树是值得的;太多的细节,太多的重复,不够大的图片。 –

+0

@AlanMoore他们帮助我学习了很多,虽然:) – FailedDev

看看这个regex reference,它会告诉你不同的字符做什么。

它说:“‘=’任选随后用‘=’后面跟着任何数目的字符不属于任何数目的字符”

,但你真的应该regular expressions

+0

+ 1的答案,我真的在非常罕见的情况下遇到了正则表达式。从来不需要阅读它。 – DarthVader

首先,让我们确保我们都在谈论同样的正则表达式。它可能创造这样的事情:

public static final Pattern CMD_LINE_ARGS_PATTERN = 
    Pattern.compile("^([^=]+)(?:(?:\\=)(.+))?$"); 

中的双反斜线(\\=)获取Java编译器转换为一个反斜杠,所以Pattern.compile()认为这是\=,转义等号。顺便说一下,这不需要逃避; ^([^=]+)(?:=(.+))?$也可以工作。

总之,该代码在这些形式之一寻找一个命令:

command 
command=arg 
command=foo,bar 
command=abc,123,xyz 

...等等。第一部分正则表达式 - ([^=]+) - 捕获“命令”,即在第一个等于(如果有)之前的所有内容,如果不是,则为整个字符串。将第二部分作为可选项,并将其与一个由量化器控制的未捕获组相关联。如果有等号(?:\\=)会消耗它,然后(.+)将捕获字符串的其余部分。

如果匹配成功,该命令将被捕获到组#1中,但我们还不知道是否有参数列表。如果没有等号,第二个捕获组将不会参加比赛,m.group(2)将返回null。否则,我们将它分成逗号分开各个参数。

但是,该代码只会把你带到目前为止。它也会接受这些输入,但是您必须测试它们以查看它们是否有效:

command= foo , bar # surrounding spaces okay/will be trimmed? 
command=foo bar  # internal spaces okay? 
command=foo,  # one-item args list, no problem 
command=,   # zero-item args list, could be trouble