2016-06-23 34 views
2

這個問題已經持續了很長時間。這裏是一個字符串的基我喜歡搜索會:帶有可選捕獲組和正向預測的正則表達式

aa.bb.cc

每個令牌(由標記化「」)可以被成功/隨後與零個或多個基團數組索引的:

例如aa[1].bb[2][3].cc

如果我的文本包含帶有可選數組索引的標記的確切數目的字符串,我想匹配。但是,如果我想搜索的文本包含額外的'。'和令牌,我不希望任何比賽:

例如aa[1].bb[2].cc.dd

我無法找到一個模式,其中包括帶有負先行可選數組索引組(S) - 我一直在使用(?!\.) - 作爲該模式的最後部分。下面是我嘗試的模式之一:

((\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*)(?!\.) 

如果我的搜索字符串是aa[1].bb[2][3].cc的分組如下:

  1. AA [1]的.bb [2] [3] .CC
  2. AA
  3. [1]
  4. BB
  5. [2] [3]
  6. 立方厘米

但是,如果我的搜索字符串包含一個以上的道理,甚至只是「」,如上面說我想整場比賽的失敗。但是,搜索返回相同的匹配組。

回答

0

使用這種模式,它會捕捉3套的任何地方:

(?<!\.)\b((?:(?:\w+(?:\[\d+\])*)\.){2}(?:\w+(?:\[\d+\])*))(?![\w\.]) 

Demo

+0

這似乎有效,如果我改變{ 2}到{n},其中n =令牌的數量 - 1. – helmet

+0

令牌的數量 - 1是正確的,請標記爲已解決。 –

0

添加啓動的字符串錨^的開始和結束串錨$到你的正則表達式的結束將導致其只匹配包含你描述的到底是什麼,僅此而已字符串。

>>> regex = re.compile('^((\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*\.(\w+)([\[\]\w]+)*)$') 
>>> regex.findall('aa[1].bb[2][3].cc') 
[('aa[1].bb[2][3].cc', 'aa', '[1]', 'bb', '[2][3]', 'cc', '')] 
>>> regex.findall('aa[1].bb[2][3].cc.dd') 
[] 
+0

感謝格雷格。除非我的搜索字符串被'('')'綁定:'(a [1] .b [2] [3] .cc)' – helmet

0

您可以結合((\w+)(\[\d+\])*\.) 2的重複次數,然後在你的正則表達式的結尾添加(\w+)(\[\d+\])*。不要忘記使用開始端錨。

^((\w+)(\[\d+\])*\.){2}(\w+)(\[\d+\])*$ 

觀看演示:https://regex101.com/r/jG3uK7/7

0

用正則表達式表示here 我得到所需的匹配。

使用負向預測和向後看。

(?<!\.)\w{2}(\[\d+])*\.\w{2}(\[\d+])*\.\w{2}(\[\d+])*(?!\.\w+)