需要帮助设计正则表达式或pyparsing方法来修改管道中包含的所有单词

时间:2013-02-18 14:08:58

标签: python regex pyparsing

例如:

blahblah|0A 4D 5E 43|adfsdasd|92| sgagrewas|12 5E|

必须成为

blahblahx0Ax4Dx5Ex43adfsdasdx92 sgagrewasx12x5E

我正在尝试以下方面的内容:re.sub(r'\|(\w+ ?)*\|', r'x\1', a)但是我遇到的问题不仅仅是第一场比赛。

更新:看起来正则表达式不是一个好的选择。 pyparsing解决方案是否可行?

如果没有,我可以写一个简单的迭代解决方案,但我更喜欢更具可扩展性的东西。但是我遇到的困难不仅仅是第一场比赛。

UPDATE2 :我最后使用了纯python方法,它工作正常,也可以处理转义字符。

def strtohex(self, string):
    hexmode = False
    hexstring = ''
    i=0
    while i<len(string):
        if string[i] == '\\':
            i += 1
            #No escape charecters inside hex pipes
            hexstring += string[i]   
        elif string[i] == '|':
            hexmode = not hexmode
        elif string[i] == ' ':
            hexstring += '' if hexmode else  ' '
        else:
            if hexmode:
                hexstring += chr(int(string[i:i+2],16))
                i += 1
            else:
                hexstring += string[i]

        i += 1
    return hexstring

4 个答案:

答案 0 :(得分:1)

我确定你可以只使用正则表达式,但为什么要这么做?使用您的编程语言很简单:

在垂直条上打破你的字符串。如果合适,检查并替换。重组

line = 'blahblah|0A 4D 5E 43|adfsdasd|92| sgagrewas|12 5E|'
parts = line.split('|')
for i, s in enumerate(parts):
    if re.match(r'^([\dA-F]{2} )*[\dA-F]$', s):
    parts[i] = re.sub('^| ', 'x', s)
result = "".join(parts)

检查整个子字符串是否由以空格分隔的两位十六进制数组成。我假设所有十六进制字母都是大写的,如您的示例所示。

答案 1 :(得分:1)

以下是pyparsing中的情况:

from pyparsing import Word,hexnums,Suppress,OneOrMore

twoDigitHex = Word(hexnums,exact=2)
VERT = Suppress('|')

pattern = VERT + OneOrMore(twoDigitHex) + VERT

# attach parse action to prefix each 2-digit hex with 'x' and join all together
pattern.setParseAction(lambda t: ''.join('x'+tt for tt in t))

# take sample code, and use transformString to apply conversion
sample = "blahblah|0A 4D 5E 43|adfsdasd|92| sgagrewas|12 5E|"
print pattern.transformString(sample)

打印

blahblahx0Ax4Dx5Ex43adfsdasdx92 sgagrewasx12x5E

答案 2 :(得分:0)

我进行了两次:

  • 1st替换每个十六进制值
  • 然后删除空白和|

它给出了:

>>> s = 'blahblah|0A 4D 5E 43|adfsdasd|92| sgagrewas|12 5E|'
>>> re.sub(r'[| ]', r'', re.sub(r' ?([0-9A-F]{2})', r'x\1', s))
'blahblahx0Ax4Dx5Ex43adfsdasdx92sgagrewasx12x5E'

答案 3 :(得分:0)

我不认为python能够平衡正则表达式。据我所知,.NET是唯一具有此类支持的风格(它看起来非常丑陋并且维持着噩梦)。

最好在管道符号上拆分字符串,然后重新加入字符串,在奇数编号的字符串数组项上应用所需的格式(通过正则表达式,如果需要)。

编辑:第二个想法,我相信这可能会使用带有可变长度表达式的lookbehind,但不幸的是python不支持那些。 (例如,(?<=^(?:[^|]*\|[^|]*\|)*[^|]*)\|(\w+ ?)*\|

的内容