匹配除模式之外的所有内容并替换匹配的字符串

时间:2018-01-24 14:46:38

标签: python regex string

我想使用python来操作我拥有的字符串。
基本上,我想先加上" \ x"在每个十六进制字节之前,除了已经有的字节" \ x"先于他们。

我的原始字符串如下所示:

mystr = r"30336237613131\x90\x01\x0A\x90\x02\x146F6D6D616E64\x90\x01\x06\x90\x02\x0F52656C6174\x90\x01\x02\x90\x02\x50656D31\x90\x00"

我想从中创建以下字符串:

mystr = r"\x30\x33\x62\x37\x61\x31\x31\x90\x01\x0A\x90\x02\x14\x6F\x6D\x6D\x61\x6E\x64\x90\x01\x06\x90\x02\x0F\x52\x65\x6C\x61\x74\x90\x01\x02\x90\x02\x50\x65\x6D\x31\x90\x00"

我想过使用正则表达式来匹配除/\x../g之外的所有内容,并用" \ x"替换每个匹配项。可悲的是,我在没有任何成功的情况下苦苦挣扎。而且,我不确定使用正则表达式是解决此类问题的最佳方法。

4 个答案:

答案 0 :(得分:7)

正则表达式(?:\\x)?([0-9A-Z]{2}) 替换\\x$1

<强>详情:

  • (?:)非捕获组
  • ?匹配零次和一次,匹配字符串\x(如果存在)。
  • ()捕获小组
  • []匹配列表0-9A-Z
  • 中的单个字符
  • {n}完全匹配n
  • \\x String \ x
  • $1第1组。

Python代码

import re

text = R'30336237613131\x90\x01\x0A\x90\x02\x146F6D6D616E64\x90\x01\x06\x90\x02\x0F52656C6174\x90\x01\x02\x90\x02\x50656D31\x90\x00'
text = re.sub(R'(?:\\x)?([0-9A-Z]{2})', R'\\x\1', text)
print(text)

<强>输出

\x30\x33\x62\x37\x61\x31\x31\x90\x01\x0A\x90\x02\x14\x6F\x6D\x6D\x61\x6E\x64\x90\x01\x06\x90\x02\x0F\x52\x65\x6C\x61\x74\x90\x01\x02\x90\x02\x50\x65\x6D\x31\x90\x00

Code demo

答案 1 :(得分:3)

你不需要正则表达式。您可以使用简单的字符串操作。首先从字符串中删除所有"\x"。然后添加每2个字符添加一次。

replaced = mystr.replace(r"\x", "")
newstr = "".join([r"\x" + replaced[i*2:(i+1)*2] for i in range(len(replaced)/2)])

输出:

>>> print(newstr)
\x30\x33\x62\x37\x61\x31\x31\x90\x01\x0A\x90\x02\x14\x6F\x6D\x6D\x61\x6E\x64\x90\x01\x06\x90\x02\x0F\x52\x65\x6C\x61\x74\x90\x01\x02\x90\x02\x50\x65\x6D\x31\x90\x00

答案 2 :(得分:0)

您可以按照自己的意愿获得一个包含值的列表,并使用更简单的重新模式

mystr = r"30336237613131\x90\x01\x0A\x90\x02\x146F6D6D616E64\x90\x01\x06\x90\x02\x0F52656C6174\x90\x01\x02\x90\x02\x50656D31\x90\x00"

import re

pat = r'([a-fA-F0-9]{2})'
match = re.findall(pat, mystr)

if match:
    print('\n\nNew string:')
    print('\\x' + '\\x'.join(match))
    #for elem in match: # match gives you a list of strings with the hex values
    #    print('\\x{}'.format(elem), end='')

print('\n\nOriginal string:')
print(mystr)

答案 3 :(得分:0)

这可以在不使用正面观察和负面前瞻的组合替换现有(?!(?<=\\x)|(?<=\\x[a-f\d]))([a-f\d]{2}) 的情况下完成。

import re

regex = r"(?!(?<=\\x)|(?<=\\x[a-f\d]))([a-f\d]{2})"
test_str = r"30336237613131\x90\x01\x0A\x90\x02\x146F6D6D616E64\x90\x01\x06\x90\x02\x0F52656C6174\x90\x01\x02\x90\x02\x50656D31\x90\x00"
subst = r"\\x$1"

result = re.sub(regex, subst, test_str, 0, re.IGNORECASE)

if result:
    print (result)

用法

See code in use here

(?!(?<=\\x)|(?<=\\x[a-f\d]))

解释

  • (?<=\\x)否定前瞻,确保以下任何一项都不匹配。
    • \x确保前面的正面观察是(?<=\\x[a-f\d])
    • \x确定前面的正面值是([a-f\d]{2})后跟一个十六进制数字。
  • {{1}}将任意两个十六进制数字捕获到捕获组1中。