2017-07-24 62 views
0

執行Python中的正則表達式搜索時,即使不啓用re.MULTILINEPython的正則表達式可以防止用' s'跨越換行符嗎?

表達A[\s]B將對陣

A 
B 

由於換行符匹配\s

除了將字符串拆分爲行並對其進行操作 - 是否有一種有效的方法可以使表達式在換行符上分隔?


編輯:我知道它可以使用[\t ][^\S\r\n],問題是我不控制輸入在這種情況下,用戶將進入\s並不會期望它spand線。我不想嘗試告訴用戶他們錯了,從他們的角度來看,這是一個錯誤。

所以如果答案是「這是不能沒有拆分線」 - 這樣吧。


請注意,逐行操作文件大約是我測試中的兩倍。

+0

你問如何只匹配*水平空白*? –

+0

我這麼認爲,是的。 – ideasman42

+0

使用'[^ ​​\ S \ r \ n]' –

回答

0

簡短的回答是否定的,Python的正則表達式不能這樣\s不會匹配\n

你可以做的是在匹配中檢測'\ n'並跳過這些。

def finditer_delimit_newlines(pattern, string, delimit_newlines=True): 
    matches = list(re.finditer(pattern, string)) 
    if not matches: 
     return [] 

    end = matches[-1].start() 
    newline_table = {-1: 0} 
    for i, m in enumerate(re.finditer(r'\n', string), 1): 
     offset = m.start() 
     newline_table[offset] = i 
     if offset > end: 
      break 

    for m in matches: 
     m_start = m.start() 
     m_end = m.end() 
     newline_offset = string.rfind('\n', 0, m_start) 
     newline_end = string.find('\n', m_end) 
     if delimit_newlines: 
      if ((newline_table[newline_offset] + 1) != 
       (newline_table[newline_end] 
       if newline_end != -1 else len(newline_table)) 
      ): 
       continue 
     yield m 


search = """A 
B 

A B""" 

import re 

for delimit_newlines in (False, True): 
    print("Test:", delimit_newlines) 
    for a in finditer_delimit_newlines(r'[A-Z]\s[A-Z]', search, delimit_newlines): 
     print(a) 

該測試輸出

Test: False 
<_sre.SRE_Match object; span=(0, 3), match='A\nB'> 
<_sre.SRE_Match object; span=(5, 8), match='A B'> 
Test: True 
<_sre.SRE_Match object; span=(5, 8), match='A B'> 

編輯,一場比賽可以捕捉尾隨換行符 定期空白的一部分,而它可以檢測到這一點,它可能是簡單的使用類似的方法如果換行符存在,則在有限範圍內重新匹配結果。

0

從技術上講,\s僅僅是[ \t\r\n\f]

速記這意味着運行替換所有([^\\]|^)(\\\\)*\\s$1$2[ \t\r\n\f]的正則表達式模式將沒有任何效果。 (不得不捕捉轉義的\s)所以技術上來說,你可以簡化上面這樣的人物類\s只是[ \t]

當然,正如其他人所說的,在不告訴最終用戶的情況下更改正則表達式的功能是非常糟糕的,並且可能更容易解釋/實現用正則表達式替換字符類[ \t](as這是對基本規則集的較小更改)。如果最終用戶認爲\s不能捕獲新行,那麼最終用戶可能會以最終用戶期望的相同方式解析文件,以便代碼邏輯與最終用戶邏輯相匹配。

相關問題