2011-05-24 34 views
4

給出以下示例字符串:"[ One].[Two ].[ Three ].[Four]" 我想匹配「One」; 「二」,「三」和「四」。正則表達式 - 在字符之間獲取詞

換句話說:我需要得到括號內的單詞,而不管這個單詞有多少空白。

我用下面的表達式試了一下:

(?<=\[)(?s)(.*?)(?=\s*\]) 

導致" One""Two"" Three""Four"

編輯: 它更有點複雜,比我第一個因子評分這將是:

  1. 有由支架壓縮了(至少一個)字(S)這可能是由任意分隔字符(例如"[one]""[one] [two][three].[four]")。
  2. 托架包含一個字和許多,或甚至沒有空格(例如"[one]""[two ]""[ three ]"
  3. 字的這些塊並有包圍支架由字符的已知序列包圍: "These words [word-1] .. [word-n] are well known""These words [word-1] .. [word-n] are well known"

請注意:"[word-1] .. [word-n]"只是代表上述區塊的任意數。

我想匹配正好罪(括號內)和刪除環繞序列("These words""are well known")以及括號內和塊之間可能存在的空格。另外,塊之間可能存在的char(它不能超過一個)也應該被刪除。 希望這不是太奇怪了;)

+0

順便說一下''(?s)'設置了點全部標誌,所以'.'與新行相匹配。那是故意的嗎?什麼是'。*?'預計會匹配?使用'\ w'是解決你的問題的一種方法,它適用。 – Kobi 2011-05-24 17:38:03

回答

10

你可以利用這一點,與 「全球」 標誌啓用

\[\s*(\S+?)\s*\] 

說明

 
\[  # a literal "[" 
\s*  # any number of white space 
(\S+?) # at least one non white-space character, non-greedily (group 1) 
\s*  # any number of white space 
\]  # a literal "]" 

編輯:

@Kobi指出,\S+?實際上可以匹配]在像"[ One]"這樣的目標中。因此,暫時第1組將包含"One]"

但是在正則表達式的末尾仍然有\],此時正則表達式引擎會回溯並給出"]"\],所以表達式可以成功。

這裏使用在線貪婪匹配非常重要(\S+?,而不是\S+)。我的答案的第一個版本中也出現了錯誤。

此外,\S是非常不確定的。如果你有什麼更具體的關於什麼「一個字」是你的 - 通過一切手段,使用它。

+0

+1分解 – Greg 2011-05-24 17:28:26

+0

非常感謝您的回答。我已經更新了最初的帖子,並詳細描述了我的要求。也許你可以再次幫助我。提前致謝。 – 0xbadf00d 2011-05-25 05:56:56

4

非貪心匹配是關鍵。請嘗試以下操作:

\[\s*(.+?)\s*\] 

它將匹配括號內什麼和之前或之後捕捉到它沒有空格。如果括號內的字符串不能有空格,我推薦以下內容,因爲它是更好的表達式。

\[\s*(\S+)\s*\] 
+0

+1 for *「非貪婪匹配是關鍵」* - 我自己一開始就弄錯了那個。 – Tomalak 2011-05-24 17:57:06

+0

謝謝。我不確定OP是否與括號內的一個單詞匹配。雖然我喜歡儘可能嚴格,但我想我會用一個靈活的表達來回答。 – 2011-05-24 18:23:35

+0

如果這些詞是衆所周知的,那麼您可以直接將它們添加到正則表達式中('word-1 | word-2 | etc)'來替代'(\ S +?)'。 – Tomalak 2011-05-25 06:59:55

3

一個簡單的解決方案是使用捕獲組來得到你真正想要的比賽的一部分:

\[\s*(.*?)\s*\] 

例子:

MatchCollection matches = Regex.Matches(s, @"\[\s*(.*?)\s*\]"); 
string[] words = matches.Cast<Match>().Select(m => m.Groups[1].Value).ToArray(); 

類似的選項是使用微調:

MatchCollection matches = Regex.Matches(s, @"\[([^\]]*)\]"); 
string[] words = matches.Cast<Match>().Select(m => m.Groups[1].Value.Trim()).ToArray(); 

如果你真的LY願意,你可以使用查找變通:

(?<=\[\s*)\S.*?(?=\s*\]) 

例子:

MatchCollection matches = Regex.Matches(s, @"(?<=\[\s*)\S.*?(?=\s*\])"); 
string[] words = matches.Cast<Match>().Select(m => m.Value).ToArray(); 
+0

+1表示環境:) - 我想補充說,可變長度後視不適用於所有正則表達式方言。 – Tomalak 2011-05-24 17:24:10

+0

@Tomalak - 謝謝。實際上我現在遇到了''P''這個模式的一些問題,在我添加'\ S'之前它匹配了第二個空格,現在它可能匹配''''也許我應該有'[^ \ s \]]'而不是。然後再次,也許'\ w'與OP一致... – Kobi 2011-05-24 17:35:24

+0

您是對的。我完全忽略了這一點!馬上改變我的答案。謝謝! *再次,'\ S +'會回溯,所以'\]'可以匹配 - 也許它不是完全錯誤的,那麼* – Tomalak 2011-05-24 17:37:35

0

正則表達式是絕對有必要嗎?如果沒有,我相信你可以修剪掉括號,點和空格。

char[] chars = new char[] {'[', ']', '.', ' '}; 
inputString = inputString.Trim(chars); 
相關問題