簡體   English   中英

除括號中的逗號外的所有逗號的索引

[英]Index of all commas except those in parentheses

如何排除小括號(少於 20 個字符)中的逗號?

獲取這個逗號的索引,但是(不是這個,逗號)。 獲取其他逗號,例如,或,或,1,1 2,2。 (不是這個,)但是(如果括號內有超過 20 個字符,則獲取此逗號的索引)

此示例的預期 output 所有逗號索引: [23, 71, 76, 79, 82, 87, 132]

在此處輸入圖像描述

正則表達式模式:( (,)|(\([^()]{0,20}\))

這種模式背后的直覺:

  • (,)查找所有逗號。 這些存儲在捕獲組 1 中。

  • (\([^()]{0,20}\))查找所有括號之間最多包含 20 個字符的括號。 這些存儲在捕獲組 2 中。

然后,我們可以從組 1 中找到所有匹配項,僅排除長度為 20 的括號內的逗號。

現在要查找這些匹配的索引,使用re.finditer()結合Match.start()Match.group()來查找第 1 組中每個匹配的起始索引:

import re

string = """Get index of this comma, but (not this , comma). Get other commas like , or ,or, 1,1 2 ,2.
(not this ,) BUT (get index of this comma, if more than 20 characters are inside the parentheses)"""

indices = [m.start(1) for m in re.finditer('(,)|(\([^()]{0,20}\))', string) if m.group(1)]

print(indices)
# > [23, 71, 76, 79, 82, 87, 132]
print([string[index] for index in indices])
# > [',', ',', ',', ',', ',', ',', ',']

m.start(1)返回第 1 組匹配的起始索引。 由於re.finditer()返回來自所有捕獲組的匹配項,因此添加if m.group(1)要求為組 1 找到匹配項(來自其他組的匹配項為None )。

編輯:這將忽略內部包含 20 個或更少字符的括號,這與您的第一個語句不一致,但與示例解釋的內容一致。 如果您想要少於20 個,只需使用{0,19}

您還可以使用帶有SKIP FAILPyPi 正則表達式模塊來匹配和排除您不希望在匹配結果中出現的字符。

在這種情況下,您可以在不應匹配逗號的括號之間匹配 1-20。

\([^()]{1,20}\)(*SKIP)(*FAIL)|,

解釋

  • \(匹配(
  • [^()]{1,20}匹配除()以外的任何字符 1-20 次
  • \)匹配)
  • (*SKIP)(*FAIL)從匹配結果中排除字符
  • | 或者
  • ,匹配一個逗號

正則表達式演示| Python 演示

示例代碼

import regex

s = """Get index of this comma, but (not this , comma). Get other commas like , or ,or, 1,1 2 ,2.
(not this ,) BUT (get index of this comma, if more than 20 characters are inside the parentheses)"""
pattern = r"\([^()]{1,20}\)(*SKIP)(*FAIL)|,"
indices = [m.start(0) for m in regex.finditer(pattern, s)]
print(indices)

Output

[23, 71, 76, 79, 82, 87, 132]

使用 PyPi 正則表達式:

,(?![^()]*\))|(?<=\((?=[^()]{20})[^()]*),

證明

Python 代碼

import regex
text = r"Get index of this comma, but (not this , comma). Get other commas like, or ,or, 1,1 2 ,2. (not this ,) BUT (get index of this comma, if more than 20 characters are inside the parentheses)"
reg_expression = r',(?![^()]*\))|(?<=\((?=[^()]{20})[^()]*),'
print(regex.sub(reg_expression, '<COMMA>\g<0></COMMA>', text))
# Get index of this comma<COMMA>,</COMMA> but (not this , comma). Get other commas like<COMMA>,</COMMA> or <COMMA>,</COMMA>or<COMMA>,</COMMA> 1<COMMA>,</COMMA>1 2 <COMMA>,</COMMA>2. (not this ,) BUT (get index of this comma<COMMA>,</COMMA> if more than 20 characters are inside the parentheses)
indices = [x.start() for x in regex.finditer(reg_expression, text)]
print(indices)
# [23, 70, 75, 78, 81, 86, 131]

表達式解釋

--------------------------------------------------------------------------------
  ,                        ','
--------------------------------------------------------------------------------
  (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
    [^()]*                   any character except: '(', ')' (0 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    \)                       ')'
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
 |                        OR
--------------------------------------------------------------------------------
  (?<=                     look behind to see if there is:
--------------------------------------------------------------------------------
    \(                       '('
--------------------------------------------------------------------------------
    (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
      [^()]{20}                any character except: '(', ')' (20
                               times)
--------------------------------------------------------------------------------
    )                        end of look-ahead
--------------------------------------------------------------------------------
    [^()]*                   any character except: '(', ')' (0 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )                        end of look-behind
--------------------------------------------------------------------------------
  ,                        ','

您可以只使用帶有一些 if 語句的 for 循環。 這不是一個理想的代碼,但可以為您提供答案。 這是一個例子:

textString = 'Get index of this comma, but (not this , comma). Get other commas like , or ,or, 1,1 2 ,2.(not this ,) BUT (get index of this comma, if more than 20 characters are inside the parentheses)'
parFlag = False #flag to check ()
commas = []
lastPar = 0 #last seen ()
for i in range(len(textString)):
    if(textString[i]=='('):
        parFlag = True
        lastPar = i
    if(textString[i]==')' or i-lastPar>=20):
        parFlag = False
    if( textString[i] == ',' and not parFlag):
        commas.append(i)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM