2015-07-21 90 views
3

我正在嘗試搜索文件中的確切單詞。我通過行讀取文件並循環查找確切的單詞。由於in關鍵字不適合查找確切的單詞,因此我使用了正則表達式模式。搜索模板以包含方括號

def findWord(w): 
    return re.compile(r'\b({0})\b'.format(w), flags=re.IGNORECASE).search 

具有這種功能的問題是,是不承認括號[xyz]

例如

findWord('data_var_cod[0]')('Cod_Byte1 = DATA_VAR_COD[0]') 

回報None

findWord('data_var_cod')('Cod_Byte1 = DATA_VAR_COD') 

回報<_sre.SRE_Match object at 0x0000000015622288>

大家能否請你幫我捏捏正則表達式模式?

+0

你期望它返回什麼? –

回答

1

是因爲那正則表達式引擎的承擔方括號字符類是正則表達式字符得到這個問題你需要擺脫你的正則表達式字符。您可以使用re.escape功能:

def findWord(w): 
    return re.compile(r'\b({0})\b'.format(re.escape(w)), flags=re.IGNORECASE).search 

另外,作爲一個更Python的方式來回回讓所有的比賽,你可以使用re.fildall()返回匹配的列表或re.finditer它返回一個迭代器包含matchobjects。

但仍然這樣不完整和高效,因爲 當你使用單詞邊界時,你的內部單詞必須包含一個類型字符。

>>> ss = 'hello string [processing] in python.' 
>>>re.compile(r'\b({0})\b'.format(re.escape('[processing]')),flags=re.IGNORECASE).search(ss) 
>>> 
>>>re.compile(r'({})'.format(re.escape('[processing]')),flags=re.IGNORECASE).search(ss).group(0) 
'[processing]' 

所以我建議,如果你的話是不含有單詞字符刪除字邊界。

但你可以使用下面的正則表達式,其使用positive look around匹配,通過空間環繞或來人在字符串的結尾或領導的話,一個更普遍的方式:

r'(?: |^)({})(?=[. ]|$) ' 
+0

你好,它仍然返回None爲:findWord('data_var_cod [0]')('Cod_Byte1 = DATA_VAR_COD [0]') – BitsNPieces

+0

@BitsNPieces嗨;)你刪除了單詞邊界? – Kasramvd

+0

是的它消除了邊界後的作品!非常感謝:) – BitsNPieces

1

這是因爲[]有特殊的含義。你應該引用你正在尋找的字符串:

re.escape(regex) 

會逃避你的正則表達式。你的代碼更改爲:

return re.compile(r'\b({0})\b'.format(re.escape(w)), flags=re.IGNORECASE).search 
             ↑↑↑↑↑↑↑↑↑ 

你可以看到re.quote確實爲你的字符串,例如:

>>> w = '[xyz]' 
>>> print re.escape(w) 
\[xyz\] 
+0

你好,它仍然返回None爲:findWord('data_var_cod [0]')('Cod_Byte1 = DATA_VAR_COD [0]') – BitsNPieces

+0

@BitsNPieces它如何編譯? '''s不匹配那裏.. – Maroun

0

你需要的一個「聰明」的方式構建正則表達式:

def findWord(w): 
    if re.match(r'\w', w) and re.search(r'\w$', w): 
     return re.compile(r'\b{0}\b'.format(w), flags=re.IGNORECASE).search 
    if not re.match(r'\w', w) and not re.search(r'\w$', w): 
     return re.compile(r'{0}'.format(w), flags=re.IGNORECASE).search 
    if not re.match(r'\w', w) and re.search(r'\w$', w): 
     return re.compile(r'{0}\b'.format(w), flags=re.IGNORECASE).search 
    if re.match(r'\w', w) and not re.search(r'\w$', w): 
     return re.compile(r'\b{0}'.format(w), flags=re.IGNORECASE).search 

的問題是,一些關鍵字將僅在啓動Word文字,其他 - 只在最後,大多數會對兩端單詞字符,有的則要非單詞字符。爲了有效檢查字邊界,您需要知道關鍵字的開始/結尾是否存在單詞字符。

因此,re.match(r'\w', x)我們可以檢查如果關鍵字與單詞字符開始,如果是,則\b添加到模式,並與re.search(r'\w$', x)如果關鍵字用字字符結束,我們可以檢查。

如果你有多個關鍵字檢查一個字符串,你可以檢查this post of mine

+0

你好,什麼是x? – BitsNPieces

+0

對不起,它是'w'。 –