Regex=
"^\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)(\\s+(\\S+(\\s+(\\S+))?))?(\\s+(\\S+))?\\s*";
input= " 1 ABC DEF GHI JKL PQR ";
在上面的输入文本中,正则表达式匹配,但是有些情况下JKL可以是空格的单词,如" JKL MNO"所以正则表达式我已经像可选的
一样(\\s+(\\S+))?
虽然得到该组我的错误值,即
G1: 1 G2: ABC G3: DEF G4: GHI **G6: JKL PQR** G8:PQR
G6当MNO出现时,应该只有JKL或JKL MNO作为一个单词,你能否弄清楚我做错了什么。
答案 0 :(得分:2)
您观察到的行为是正则表达式的预期行为。捕获组从组的开始paren开始,以其结束paren结束。如果捕获组A包含捕获组B,则A将包含所有B。
那是
(\\s+(\\S+(\\s+(\\S+))?))?
与
匹配JKL PQR
第1组将是
JKL PQR第2组将是
JKL PQR第3组将是
PQR第4组将是
PQR
如果您希望JKL成为一个组,您可以使用捕获组和非捕获组的组合,例如:
(?:\\s+(?:(\\S+)(?:\\s+(\\S+))?))?
然后,第1组将为JKL
,第2组将为PQR
。
答案 1 :(得分:1)
发生的事情是,(\\s+(\\S+))?
部分的内部(\\s+(\\S+(\\s+(\\S+))?))
读取PQR
并且正则表达式的最后部分 - (\\s+(\\S+))?
是可选的,最终无法读取任何内容
使最后一部分不可选将解决问题。但是,如果您不打算捕获它们,则可以避免使用这么多捕获组,例如,可以使空格不被捕获 - (?:\\s+)
所以,您可以将正则表达式更改为:
String str = "^\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)(?:\\s+(\\S+(?:\\s+\\S+)?))?(?:\\s+(\\S+))\\s*";
请注意这里关注的部分:
(?:\\s+(\\S+(?:\\s+\\S+)?))?
正如您所看到的,只有一个捕获组,足以捕获JKL
和JKL MNO
(如果存在)。如果您还想单独捕获MNO
,请将内部\\S+
也设为捕获组。
答案 2 :(得分:0)
如果PQR
是强制性的,则删除?
中的最后一个(\\s+(\\S+))?
即可。
这是因为RegEx是贪婪的,所以如果最后一部分是可选的(这是问题),它将在第8组中PQR
。
完整的正则表达式应该是:
"^\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)(\\s+(\\S+(\\s+(\\S+))?))?(\\s+(\\S+))\\s*"
答案 3 :(得分:0)
我认为你在寻找的是:
^\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)(\\s+(\\S+(\\s+(\\S+))??))?(\\s+(\\S+))?\\s*$
该模式使用不情愿(非贪婪)量词??
。这意味着仅在必要时才匹配组7。
如果缺少" MNO"
,则组7根本不匹配。第6组仅包含" JKL"
。
如果您使用字符串锚点的结尾,则会强制" MNO"
与第7组匹配,即使此组是可选的,但是不情愿的量词??
。第6组包含" JKL MNO"
没有不情愿的量词,因为模式是从左到右评估的," PQR"
将与第7组匹配(因为量词?
默认是贪婪的)并且第9组将不匹配因为它是可选的。
注意:没有无用的捕获组,您可以写:
^\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)(?:\\s+(?:(\\S+)(?:\\s+(\\S+))??))?(?:\\s+(\\S+))?\\s*$
答案 4 :(得分:0)
而不是使用让我的眼睛游泳的正则表达式,我会去分手:
String[] toks = input.split( "\\s+" );
toks.length必须至少为4,以便我们toks[0]
到toks[3]
。现在:
那么toks.length == 6怎么样?是可选的" MNO"强于可选的" PQR"还是反过来呢?在任何一种情况下,您都可以使用String []及其长度更轻松地决定。
(我知道" JKL"和" MNO"之间的空格数会以这种方式丢失。如果真的很重要,可以从原来的字符串中检索到努力。)