2012-02-28 108 views
2

我已經搜索過,但並未完全找到適合我的情況。基本上,我試圖分裂以下行:在Python中解析和切割長字符串

(CU!DIVD:WEXP:DIVD-:DIVD+:RWEXP:RDIVD:RECL:RLOSS:MISCDI:WEXP-:INT:RGAIN:DIVOP:RRGAIN:DIVOP-:RDIVOP:RRECL:RBRECL:INT -:RRLOSS:INT +:RINT:RDIVD-:RECL-:RWXPOR:WEXPOR:MISCRE:WEXP+:RWEXP-:RBWEXP:RECL+:RRECL-:RBDIVD) 

你可以看這是CU不是DIVD或WEXP或DIV-或等等。

(CU!DIVD:WEXP:DIVD-:DIVD+:RWEXP:RDIVD:RECL:RLOSS:MISCDI:WEXP-) 
(CU!INT:RGAIN:DIVOP:RRGAIN:DIVOP-:RDIVOP:RRECL:RBRECL:INT-) 
(CU!RRLOSS:INT +:RINT:RDIVD-:RECL-:RWXPOR:WEXPOR:MISCRE:WEXP+) 
(CU!RWEXP-:RBWEXP:RECL+:RRECL-:RBDIVD) 

他們都少於65個字符:如果是超過65個字符到的東西更容易管理這樣我想要做的是分裂這一行。這可以存儲在一個列表中,我可以照顧其餘的。我開始使用RegEx處理此問題,但我遇到了一些麻煩。

此外,還可以有以下條件語句:

  • <
  • >
  • =
  • !=
  • ! !<
  • >

截至目前,我有這樣的:

def FilterParser(iteratorIn, headerIn): 
    listOfStrings = [] 
    for eachItem in iteratorIn: 
     if len(str(eachItem.text)) > 65: 
      exmlLogger.error('The length of filter' + eachItem.text + ' exceeds the limit and will be dropped') 
      pass 
     else: 
      listOfStrings.append(rightSpaceFill(headerIn + EXUTIL.intToString(eachItem),80)) 
return ''.join(stringArray) 

回答

2

下面是使用正則表達式的解決方案,編輯成包括CU!前綴(或任何其他前綴)至年初每個新行:

import re 
s = '(CU!DIVD:WEXP:DIVD-:DIVD+:RWEXP:RDIVD:RECL:RLOSS:MISCDI:WEXP-:INT:RGAIN:DIVOP:RRGAIN:DIVOP-:RDIVOP:RRECL:RBRECL:INT -:RRLOSS:INT +:RINT:RDIVD-:RECL-:RWXPOR:WEXPOR:MISCRE:WEXP+:RWEXP-:RBWEXP:RECL+:RRECL-:RBDIVD)' 

prefix = '(' + re.search(r'\w+(!?[=<>]|!)', s).group(0) 
maxlen = 64 - len(prefix) # max line length of 65, prefix and ')' will be added 
regex = re.compile(r'(.{1,%d})(?:$|:)' % maxlen) 
lines = [prefix + line + ')' for line in regex.findall(s[len(prefix):-1])] 

>>> print '\n'.join(lines) 
(CU!DIVD:WEXP:DIVD-:DIVD+:RWEXP:RDIVD:RECL:RLOSS:MISCDI:WEXP-) 
(CU!INT:RGAIN:DIVOP:RRGAIN:DIVOP-:RDIVOP:RRECL:RBRECL:INT -) 
(CU!RRLOSS:INT +:RINT:RDIVD-:RECL-:RWXPOR:WEXPOR:MISCRE:WEXP+) 
(CU!RWEXP-:RBWEXP:RECL+:RRECL-:RBDIVD) 

首先,我們需要抓住前綴,我們做到這一點使用re.search().group(0),它返回整場比賽。每個最後一行最多不得超過65個字符,我們將用於獲取這些行的正則表達式不會包含前綴或右括號,這就是爲什麼maxlen64 - len(prefix)

既然我們知道了我們可以匹配的最多字符,那麼正則表達式(.{1,<maxlen>)的第一部分將會匹配至多許多字符。末尾的部分(?:$|:)用於確保我們只將字符串拆分爲分號或字符串末尾。由於只有一個捕獲組regex.findall()將僅返回該匹配,因此只能返回尾部的分號。下面是它看起來像你的樣品字符串:

>>> pprint.pprint(regex.findall(s[len(prefix):-1])) 
['DIVD:WEXP:DIVD-:DIVD+:RWEXP:RDIVD:RECL:RLOSS:MISCDI:WEXP-', 
'INT:RGAIN:DIVOP:RRGAIN:DIVOP-:RDIVOP:RRECL:RBRECL:INT -', 
'RRLOSS:INT +:RINT:RDIVD-:RECL-:RWXPOR:WEXPOR:MISCRE:WEXP+', 
'RWEXP-:RBWEXP:RECL+:RRECL-:RBDIVD'] 

列表內涵被用於通過添加前綴和後)每個結果構建的所有行的列表。 s的切片已完成,以便在regex.findall()之前將前綴和尾部)從原始字符串中剝離。希望這可以幫助!

+0

這是一個很好的開始!我會如何'優雅地'剝下CU! (或者就此而言,任何字母數字和隨附的條件)並將其附加到每個新行? – Carlos 2012-02-28 22:09:35

+0

@ mastashake57 - 對不起,看起來我錯過了你的問題的元素,現在正在編輯。 – 2012-02-28 22:16:46

+0

謝謝F.J.,你在幫我。順便說一句,完全欣賞故障。 – Carlos 2012-02-28 22:21:40