2012-02-28 15 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