3

Docklight と呼ばれるシリアル監視プログラムの出力を解析したい (強くお勧めします) 「16 進数」文字列を出力します: または (2 つの大文字の 16 進数の後にスペースが続きます) のシーケンスを出力します。対応する正規表現は次のとおり([0-9A-F]{2} )+です。例:'05 03 DA 4B 3F '

プログラムが特定の文字列を検出すると、「16 進数」文字列にコメントを配置します。例えば:

'05 03 04 01 0A  The Header 03 08 0B BD AF  The PAYLOAD 0D 0A  The Footer'

コメントは、次の形式の文字列です' .+ '(スペースが先行し、スペースが後続する一連の文字)。

コメントを消したいです。たとえば、フィルタリングされた上記の「16 進数」文字列は次のようになります。

'05 03 04 01 0A 03 08 0B BD AF 0D 0A '

正規表現でこれを行うにはどうすればよいですか?

4

6 に答える 6

4

あなたが試すことができますre.findall()

>>> a='05 03 04 01 0A  The Header 03 08 0B BD AF  The PAYLOAD 0D 0A  The Footer'
>>> re.findall(r"\b[0-9A-F]{2}\b", a)
['05', '03', '04', '01', '0A', '03', '08', '0B', 'BD', 'AF', '0D', '0A']

正規表現の\bは「単語境界」に一致します。

もちろん、シリアル モニタが のようなものを挿入すると、入力があいまいになりますTHIS BE THE HEADER

于 2010-08-03T10:36:17.140 に答える
0

挿入された文字列に一致が含まれていないと仮定すると、すべての 16 進数を見つける方が簡単かもしれません。

>>> data = '05 03 04 01 0A  The Header 03 08 0B BD AF  The PAYLOAD 0D 0A  The Footer'
>>> import re
>>> pattern = re.compile("[0-9A-F]{2} ")
>>> "".join(pattern.findall(data))
'05 03 04 01 0A 03 08 0B BD AF AD 0D 0A '

それ以外の場合は、挿入された文字列の前に 2 つのスペースがあるという事実を利用できます。

>>> data = '05 03 04 01 0A  The Header 03 08 0B BD AF  The PAYLOAD 0D 0A  The Footer'
>>> re.sub("(  .*?)(?=( [0-9A-F]{2} |$))","",data)
'05 03 04 01 0A 03 08 0B BD AF 0D 0A'

これは、先読みを使用して、挿入された文字列がいつ終了するかを判断します。スペースで囲まれた 16 進文字列またはソース文字列の末尾を探します。

于 2010-08-03T10:37:55.303 に答える
0

すべての 16 進数を見つける 2 つの回答を既に受け取っていますが、これは、16 進数のように見えないすべてのテキストを見つける直接の正規表現と同じです (大文字/小文字の 2 つの文字/数字であると仮定すると、0-9 と AF範囲、その後にスペース)。

このようなもの(申し訳ありませんが、私はpythoneerではありませんが、アイデアはわかります):

newstring = re.sub(r"[^ ]+(?<![0-9A-Fa-f ]{2}|^.)", "", yourstring)

「振り返る」ことで機能します。連続する非スペース部分文字列をすべて見つけてから、 で否定的に検索し(?<!....)ます。「前の 2 文字が 16 進数でない場合は、成功します」と表示されます。^.末尾の小さな文字列は、文字列の最初の文字が誤って一致するのを防ぎます。

編集

Alan Moore が提案したように、肯定的な先読み表現を使用した同じアイデアを次に示します。

newstring = re.sub(r"(?>\b[0-9A-Fa-f ]{2}\b)", "", yourstring)
于 2010-08-03T10:47:35.317 に答える
0

なぜ正規表現?私にとってよりPythonicは(通常の数字ではなく16進数で修正されています):

command='05 03 04 01 0A  The Header 03 08 0B BD AF  The PAYLOAD 0D 0A  The Footer'
print ' '.join(com for com in command.split()
               if len(com)==2 and all(c.upper() in '0123456789ABCDEF' for c in com))
于 2010-08-03T10:53:38.173 に答える
0

正規表現の使用

hexa = '([0-9A-F]{2} )+'
" ".join(re.findall(hexa, line))
于 2010-08-03T10:46:25.770 に答える
0

実際に正規表現の否定を使用するソリューションはどうですか? ;)

result = re.sub(r"[ ]+(?:(?!\b[0-9A-F]{2}\b).)+", "", subject)
于 2010-08-03T10:53:58.967 に答える