2014-10-30 72 views
0

我试着写在这个格式的字符串匹配的Java正则表达式查找第二空间:的规则运算超过20个字符

AXXXXYYYYB 

XXXX是终止在第20个字符或字符串第二个空间,以先到者为准YYYY是一个字符串,它终止于第20个字符或第一个空间,以先到者为准。

而且我需要XXXXYYYY成为第一和第二捕获组。

我能得到它的工作在XXXX第一空间与此终止:

^A([^ ]{1,20}) ?([^ ]{1,20})B$ 

但我无法弄清楚,将终止在第20个字符或规则第二个空间。

此外,我不在乎任一捕获组是否以一个额外的前导空间或尾随空间结束。

样品输入 - >输出:

MR SMITH BROOKLYN -> "MR SMITH" and "BROOKLYN" (separated at second space) 
MR SMYTHE-JONES BRONX -> "MR SMYTHE-JONES" and "BRONX" (separated at second space) 
123456789QUEENS -> "123456789" and "QUEENS" (separated at 20th character) 
1234567890 1234567890QUEENS -> "1234567890 123456789" and "0QUEENS" (separated at 20th character) 
1234567890 1234567890STATEN ISLAND -> "1234567890 123456789" and "0STATEN" (separated at 20th character, then separated at space) 
+1

你能提供与预期输出的例子吗? – 2014-10-30 04:03:40

+0

是的,我一注意到保存就立即注意到,并在您发布澄清请求时进行修复。抱歉! – lavinio 2014-10-30 04:14:19

+0

只有1个空格和少于20个字符的字符串会发生什么变化? – vks 2014-10-30 04:25:18

回答

1
^([^ ]+[ ][^ ]+)[ ](.*)$|(.{20})(.*)$ 

您可以尝试this.Grab的捕获。

1)([^ ]+[ ][^ ]+)[ ](.*)将打破第二空间

2)(.{20})(.*)将打破上20个字符。

查看演示。

http://regex101.com/r/gT6kI4/4

+0

如果第一个字符串> 20个字符,但总字符串中有两个空格,则会返回第一个字符串> 20个字符。 MR SUPERDUPERLONGNAMESMITH BROOKLYN将返回第一个字符串太长。你错过了“以先到者为准”的部分。 – lavinio 2014-10-30 04:38:45

+0

@lavinio http://regex101.com/r/gT6kI4/5 ????? – vks 2014-10-30 04:41:53

+0

更接近,但是“MR SMITHERLY BROOKLYN”突破“MR SMITHERLY BROOKLY”和“N”而不是“MR SMITHERLY”和“BROOKLYN”。 – lavinio 2014-10-30 05:10:56

0

,我不认为这会使用一个正则表达式来完成。
我建议先运行这个模式:
^(.{20})(.*)$
if sub-pattern no。 1包含那么多一个空间失败并运行该模式,而不是
^(\S+\s\S+)\s(.*)$

+0

如果第一个字符串> 20个字符,但总字符串中有两个空格,这将返回第一个> 20个字符的字符串。 MR SUPERDUPERLONGNAMESMITH BROOKLYN将返回第一个字符串太长。你错过了“以先到者为准”的部分。 – lavinio 2014-10-30 04:39:02

1

这是我的解决方案,它利用回顾后发的:

"([^ ]*(?:[ ][^ ]*)?)(?<!.{21})[ ]?([^ ]{0,20})" 

([^ ]*(?:[ ][^ ]*)?)(?<!.{21})比赛和捕获的第一部分,它必须是严格小于21个字符包含最多一个空格。由于贪婪的量词,它总是会尝试尽可能长的字符串(总是首先匹配第一个空格),并在被后视限制时缩短其长度。只有在找不到21个字符才能匹配时,lookbehind才允许匹配器继续进行,这意味着前面的部分少于20个字符。

由于第一部分可以以空格结尾,因此我需要将它与[ ]?匹配。

然后,由于第二部分不能包含任何空间(因为它在第一个空格处破裂),所以它可以简单地通过([^ ]{0,20})进行匹配和捕获。

请注意,此解决方案假定输入字符串中没有行分隔符字符。

有一个警告:第一部分可能包含尾部空格,如果它是第一个空格并且是第20个字符。您可以防止通过使一个小的变化:

"([^ ]*(?:[ ][^ ]+)?)(?<!.{21})[ ]?([^ ]{0,20})" 
       ^

Demo on ideone