#python #regex
#python #регулярное выражение
Вопрос:
Я пытаюсь создать регулярное выражение, которое будет выполнять поиск всех 12-значных шестнадцатеричных значений в файле. Например: строка 448699 => шестнадцатеричное 343438363939. Регулярное выражение, которое у меня есть сейчас, это:
(r'3[0-9]d{10}')
первому символу соответствует 3, второму 0-9, а следующие 10 — это любые случайные цифры. Приведенный выше шестнадцатеричный код состоит из 12 цифр и начинается с первого символа, каждый второй символ равен 3. Как бы я выразил это с помощью регулярного выражения. Я думал примерно о следующем, но не уверен:
(r'3[0-9]3[0-9]3[0-9]3[0-9]3[0-9]3[0-9]')
Ответ №1:
Вы действительно близки к цели. Требуемый шаблон:
(r'(?:3d){6}')
Редактировать — Как указал Майк Пеннингтон, шестнадцатеричные числа могут включать буквы A-F. На самом деле я не был уверен в назначении правила «каждая вторая цифра равна 3», поэтому я оставил правила такими, как вы их описали.
Комментарии:
1. @Justin Morgan Это регулярное выражение возвращает только первые 2 цифры. Я искал шаблоны типа: длиной 12 цифр и x = 0-9 => 3x3x3x3x3x3x
2. @user706808 — Оно должно вернуть полную 12-значную последовательность. Возможно, вы смотрите на группу захвата, которая будет содержать каждую пару «3x». Я изменил его на группу без захвата, попробуйте сейчас. Вы также можете протестировать это здесь: rubular.com/r/QUeiOqjNB6 и версия, которая принимает шестнадцатеричные цифры A-F: rubular.com/r/6yorlzZzZM (обратите внимание на флаг нечувствительности к регистру).
3. @Justin Morgan, который это сделал… Мне нужно потратить время на изучение regexp. Они такие мощные! Что вы имели в виду под группой захвата против группы без захвата?
4. @user706808 — Обычно, когда вы заключаете в круглые скобки вложенный шаблон в regex, движок сохраняет все, что соответствует этому вложенному шаблону, на потом. Это немного сложно объяснить; ознакомьтесь с этой справочной информацией о группировке и обратных ссылках .
5. @Justin Morgan — Мне интересно еще кое-что: если в файле есть значение ascii (например, 115 15 110 110), другое регулярное выражение, которое я использую, не найдет его, если я не уберу пробел между строкой. Реально, это может произойти в файлах журнала. Может ли regxp игнорировать только пробелы?
Ответ №2:
Царит полная неразбериха…
Если вы хотите сопоставить результат преобразования ЛЮБОЙ 6-байтовой последовательности в строку из 12 шестнадцатеричных цифр (то, что вы просили), вам нужно [0-9a-fA-F]{12}
.
Если вы хотите сопоставить результат преобразования 6-байтовой последовательности десятичных цифр ASCII в строку из 12 шестнадцатеричных цифр (что указано в вашем примере кода), вам нужно (?:3[0-9]){6}
.
Придирка: Вам не следует использовать d
так, как если бы вы использовали Unicode, он подберет любые десятичные цифры, отличные от ASCII, которые НЕ являются шестнадцатеричными цифрами (более 300 вариантов).
Предложение (3[0-9a-fA-F]){6}
обнаруживает 6-байтовые последовательности байтов, взятых из 0123456789:;<=>?
, которые вряд ли будут тем, что вы хотите.
Обновление с запросом на разъяснение.
Пожалуйста, рассмотрите следующее и сообщите нам, какой шаблон на самом деле находит то, что вы хотите, и не пропускает «ложные срабатывания» через ворота.
>>> import re, binascii
>>> originals = ('123456', 'FOOBAR', ':;<=>?')
>>> data = ' '.join(map(binascii.hexlify, originals))
>>> print data
313233343536 464f4f424152 3a3b3c3d3e3f
>>> for pattern in (r'(?:3d){6}', r'(3[0-9a-fA-F]){6}',
... r'(?:3[0-9a-fA-F]){6}', r'[0-9a-fA-F]{12}'):
... print repr(pattern), re.findall(pattern, data)
...
'(?:3\d){6}' ['313233343536']
'(3[0-9a-fA-F]){6}' ['36', '3f']
'(?:3[0-9a-fA-F]){6}' ['313233343536', '3a3b3c3d3e3f']
'[0-9a-fA-F]{12}' ['313233343536', '464f4f424152', '3a3b3c3d3e3f']
Комментарии:
1. Я действительно ценю разъяснение. Я вижу, что мне нужно потратить некоторое время на регулярное выражение… Я все еще пытаюсь понять, как / почему [0-9a-fA-F]{12} работает, но это так!
2. @пользователь706808: Пожалуйста, уточните «работает». Пожалуйста, уточните, какую из 3 вышеперечисленных возможностей вы хотите. Очевидно, вы хотите, чтобы «3031323435» соответствовало. Как насчет «3a3b3c3d3e3f»? Как насчет «fffffffffffff»?
3. Сегодня утром я могу мыслить немного более четко… долгая неделя. Потратив некоторое время на регулярное выражение, я обнаружил, что регулярному выражению необходимо найти строку (когда x = 0-9): 3x3x3x3x3x3x …. Это шаблон, который можно найти в файле журнала, когда я конвертирую первые 6 цифр 16-значного числа на …. Устройство, считывающее число, берет последовательность и преобразует ее в шестнадцатеричную форму исходного числа, с 3, которое теперь предшествует исходному числу, и каждой последующей цифрой этого числа (hex). Я проверяю, что это число не отображается в открытом виде в журналах.
4. @Mike Pennington — добавлен комментарий.
Ответ №3:
Вы почти на месте … поскольку шестнадцатеричное значение может иметь a-f
, вам нужно включить их…
(r'(3[0-9a-fA-F]){6}')
Комментарии:
1. @Mike Pennington:
binascii.hexlify(':;<=>?')
выдает'3a3b3c3d3e3f'
то, что соответствует вашему ответу… пожалуйста, пересмотрите.2. @John Machin, пожалуйста, поясните, в чем проблема… Цитируя OP,
The hex above is 12 digits and starting with the first character, every other character is a 3. How would I express this with regexp.
формулировка немного неясна, но строка, которую вы мне дали, кажется, соответствует описанию в комментарии к OP. Кроме того, он уже принял ответ, похожий на мой, и фактически они сказали, что им действительно нужен мой ответ… итак, смысл в том??3. @Майк Пеннингтон: Смотрите мой ответ. Формулировка очень неясна. Вы выбрали наименее правдоподобный из 3 вариантов.
4. @John Machin, позвольте мне процитировать OP,
I'm still trying to understand how/why [0-9a-fA-F]{12} works, but it does!
. Не могли бы мы, пожалуйста, сначала обсудить это с ним?5. @Mike Pennington: О, действительно, это было бы так, вот почему я каталогизировал все три возможности в своем ответе — однако OP изменил свой принятый ответ на мой, а затем обратно без какой-либо попытки прояснить, чего он действительно хотел.