2014-10-30 27 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