Раздельный поиск определенного шаблона [дубликат]

Я нашел еще одну проблему, вызвавшую эту проблему, и уже решил ее. Я случайно сохранил свой скрипт в кодировке UTF-16. Похоже, что PHP5 не может распознать тег <?php в 16-битной кодировке по умолчанию.

160
задан Guy 30 October 2014 в 22:27
поделиться

13 ответов

Я согласен, что по определению ваше регулярное выражение не пропускает UUID. Однако может быть полезно отметить, что если вы ищете особенно глобальные уникальные идентификаторы Microsoft (GUID), существует пять эквивалентных строковых представлений для GUID:

"ca761232ed4211cebacd00aa0057b223" 

"CA761232-ED42-11CE-BACD-00AA0057B223" 

"{CA761232-ED42-11CE-BACD-00AA0057B223}" 

"(CA761232-ED42-11CE-BACD-00AA0057B223)" 

"{0xCA761232, 0xED42, 0x11CE, {0xBA, 0xCD, 0x00, 0xAA, 0x00, 0x57, 0xB2, 0x23}}" 
32
ответ дан Panos 19 August 2018 в 01:25
поделиться
  • 1
    В каких ситуациях будет найден первый шаблон? Т.е. существует ли функция .Net, которая лишила бы дефисы или вернула бы GUID без дефисов? – Guy 25 September 2008 в 23:32
  • 2
    Вы можете получить его с помощью myGuid.ToString («N»). – Panos 25 September 2008 в 23:38
$UUID_RE = join '-', map { "[0-9a-z]{$_}" } 8, 4, 4, 4, 12;

BTW, разрешая только 4 на одной из позиций, действителен только для UUIDv4. Но v4 - не единственная версия UUID, которая существует. Я также встречал v1 в своей практике.

1
ответ дан abufct 19 August 2018 в 01:25
поделиться

Вариант для C ++:

#include <regex>  // Required include

...

// Source string    
std::wstring srcStr = L"String with GIUD: {4d36e96e-e325-11ce-bfc1-08002be10318} any text";

// Regex and match
std::wsmatch match;
std::wregex rx(L"(\\{[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{12}\\})", std::regex_constants::icase);

// Search
std::regex_search(srcStr, match, rx);

// Result
std::wstring strGUID       = match[1];
4
ответ дан Anton K 19 August 2018 в 01:25
поделиться

В python re вы можете перейти от номера к альфа-букве верхнего регистра. Итак.

import re
test = "01234ABCDEFGHIJKabcdefghijk01234abcdefghijkABCDEFGHIJK"
re.compile(r'[0-f]+').findall(test) # Bad: matches all uppercase alpha chars
## ['01234ABCDEFGHIJKabcdef', '01234abcdef', 'ABCDEFGHIJK']
re.compile(r'[0-F]+').findall(test) # Partial: does not match lowercase hex chars
## ['01234ABCDEF', '01234', 'ABCDEF']
re.compile(r'[0-F]+', re.I).findall(test) # Good
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']
re.compile(r'[0-f]+', re.I).findall(test) # Good
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']
re.compile(r'[0-Fa-f]+').findall(test) # Good (with uppercase-only magic)
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']
re.compile(r'[0-9a-fA-F]+').findall(test) # Good (with no magic)
## ['01234ABCDEF', 'abcdef', '01234abcdef', 'ABCDEF']

Это делает простейшее регулярное выражение UUID Python:

re_uuid = re.compile("[0-F]{8}-([0-F]{4}-){3}[0-F]{12}", re.I)

Я оставлю его как упражнение для чтения, чтобы использовать timeit для сравнения производительности эти.

Наслаждайтесь. Сохраните его Pythonic ™!

ПРИМЕЧАНИЕ. Эти интервалы также будут соответствовать :;<=>?@', поэтому, если вы подозреваете, что могли бы дать вам ложные срабатывания, не используйте ярлык. (Спасибо, Оливер Обер, за то, что указали это в комментариях.)

9
ответ дан Bruno Bronosky 19 August 2018 в 01:25
поделиться
  • 1
    [0-F] действительно будет соответствовать 0-9 и AF, но также и любой символ, код ASCII которого находится между 57 (для 9) и 65 (для A), то есть любой из:; & lt; = & gt; ». – Olivier Aubert 19 October 2015 в 08:40
  • 2
    Поэтому не используйте вышеупомянутый код, за исключением случаев, когда вы хотите рассмотреть: = & gt ;;; & lt; ;; - & lt; @ =: - @ =; = - @; @: - & gt; == @? & Gt; =: знак равно как действительный UUID :-) – Olivier Aubert 19 October 2015 в 08:48

Итак, я думаю, что у Ричарда Броноски на самом деле есть лучший ответ на сегодняшний день, но я думаю, вы можете сделать немного, чтобы сделать его несколько проще (или, по крайней мере, терре):

re_uuid = re.compile(r'[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}', re.I)
4
ответ дан ifischer 19 August 2018 в 01:25
поделиться
  • 1
    Даже терпение: re_uuid = re.compile(r'[0-9a-f]{8}(?:-[0-9a-f]{4}){4}[0-9a-f]{8}', re.I) – Pedro Gimeno 12 May 2014 в 12:01
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89AB][0-9a-f]{3}-[0-9a-f]{12}$/i

Регулярное выражение Gajus отклоняет UUID V1-3 и 5, хотя они действительны.

27
ответ дан iGEL 19 August 2018 в 01:25
поделиться
  • 1
    Но он допускает недопустимые версии (например, 8 или A) и недопустимые варианты. – Brice 13 February 2018 в 11:33
  • 2
    @Brice спасибо, исправлено – iGEL 28 February 2018 в 12:14
  • 3
    Обратите внимание, что AB в [89AB] [0-9a-f] является верхним регистром, а остальные допустимые символы - строчными. Это поймало меня на Python – Tony Sepia 19 July 2018 в 13:21

Если вы хотите проверить или проверить конкретную версию UUID, вот соответствующие регулярные выражения.

Обратите внимание, что единственное различие - номер версии, который объясняется в главе 4.1.3. Version UUID 4122 RFC .

Номер версии - это первый символ третьей группы: [VERSION_NUMBER][0-9A-F]{3}:

  • UUID v1 :
    /^[0-9A-F]{8}-[0-9A-F]{4}-[1][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
    
  • UUID v2:
    /^[0-9A-F]{8}-[0-9A-F]{4}-[2][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
    
  • UUID v3:
    /^[0-9A-F]{8}-[0-9A-F]{4}-[3][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
    
  • UUID v4:
    /^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
    
  • UUID v5:
    /^[0-9A-F]{8}-[0-9A-F]{4}-[5][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
    
47
ответ дан Ivan Gabriele 19 August 2018 в 01:25
поделиться
  • 1
    Шаблоны не включают строчные буквы. Он также должен содержать a-f рядом с каждой областью A-F. – Paweł Psztyć 26 June 2017 в 22:21
  • 2
    i в конце регулярного выражения отмечает это как нечувствительное к регистру. – johnhaley81 30 June 2017 в 03:00

Регулярное выражение для uuid:

[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
352
ответ дан Ivelin 19 August 2018 в 01:25
поделиться
  • 1
    сделайте это [a-f0-9]! Поскольку это шествие! Ваше регулярное выражение (как оно есть) может возвращать ложные срабатывания. – exhuma 25 September 2011 в 10:21
  • 2
    В некоторых случаях вы можете даже захотеть сделать это [a-fA-F0-9] или [A-F0-9]. – Hans-Peter Störr 23 November 2011 в 14:53
  • 3
    +1 для шаблона, но мне интересно [0-9a-f] может работать лучше, поскольку более случайные шестнадцатеричные цифры будут числом вместо буквенного символа? – cyber-monk 2 April 2012 в 16:46
  • 4
    @ cyber-monk: [0-9a-f] идентичен [a-f0-9] и [0123456789abcdef] по смыслу и по скорости, поскольку регулярное выражение все равно превращается в конечный автомат, причем каждая шестнадцатеричная цифра превращается в запись в таблице состояний. Для точки входа в то, как это работает, см. ru.wikipedia.org/wiki/Nondeterministic_finite_automaton – JesperSM 3 July 2012 в 13:07
  • 5
    Это решение не совсем корректно. Он соответствует идентификаторам, которые имеют неверную версию и варианты символов на RFC4122. Решение @Gajus является более правильным в этом отношении. Кроме того, RFC позволяет вводить символы верхнего регистра, поэтому добавление [A-F] было бы подходящим. – broofa 6 February 2013 в 20:35
  • 6
    – Bruno Bronosky 26 February 2013 в 00:57

Версии 4 UUID имеют форму xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx, где x - любая шестнадцатеричная цифра, а y - одна из 8, 9, A или B. например. f47ac10b-58cc-4372-a567-0e02b2c3d479.

source: http://en.wikipedia.org/wiki/Uuid#Definition

Поэтому это технически более корректно:

/[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}/
86
ответ дан Matt Keeble 19 August 2018 в 01:25
поделиться
  • 1
    Я не думаю, что вы имеете в виду a-z. – Bruno Bronosky 5 February 2013 в 18:06
  • 2
    Необходимо принять [A-F] тоже. В разделе 3 RFC4122: «Шестнадцатеричные значения« a » через "f" выводятся как символы нижнего регистра и нечувствительны к регистру на входе '. Также (:?8|9|A|B), вероятно, немного читаем как [89aAbB] – broofa 6 February 2013 в 20:26
  • 3
    Необходимо скопировать модификацию @ broofa; поскольку ваш исключает нижний регистр A или B. – ELLIOTTCABLE 18 May 2013 в 23:26
  • 4
    @elliottcable В зависимости от вашей среды просто используйте флаг i (без учета регистра). – Gajus 15 January 2014 в 01:11
  • 5
    Вы отклоняете версии с 1 по 3 и 5. Почему? – iGEL 24 June 2014 в 14:20

@ivelin: UUID может иметь капители. Таким образом, вам понадобится toLowerCase () строка или использовать:

[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}

Хотелось бы просто прокомментировать это, но не достаточно rep:)

93
ответ дан Matthew F. Robben 19 August 2018 в 01:25
поделиться
  • 1
    Обычно вы можете справиться с этим, задав шаблон как нечувствительный к регистру с i после шаблона, это делает более чистый шаблон: / [0-9a-f] {8} - [0-9a-f] {4} - [0 -9а-е] {4} - [0-9a-е] {4} - [0-9a-е] {12} / я – Thomas Bindzus 27 February 2016 в 10:07

По определению, UUID - это 32 шестнадцатеричных цифры, разделенных в 5 группах дефисами, как вы описали. Вы не должны пропустить ни одного с вашим регулярным выражением.

http://en.wikipedia.org/wiki/Uuid#Definition

9
ответ дан pix0r 19 August 2018 в 01:25
поделиться
  • 1
    Не верно. RFC4122 разрешает [1-5] для номера версии и [89aAbB] для цифры варианта. – broofa 6 February 2013 в 20:36

Для UUID, сгенерированного в OS X с uuidgen, шаблон регулярного выражения -

[A-F0-9]{8}-[A-F0-9]{4}-4[A-F0-9]{3}-[89AB][A-F0-9]{3}-[A-F0-9]{12}

Проверить с помощью

uuidgen | grep -E "[A-F0-9]{8}-[A-F0-9]{4}-4[A-F0-9]{3}-[89AB][A-F0-9]{3}-[A-F0-9]{12}"
4
ответ дан Quanlong 19 August 2018 в 01:25
поделиться

[\w]{8}(-[\w]{4}){3}-[\w]{12} работал для меня в большинстве случаев.

Или если вы хотите быть действительно конкретным [\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}.

13
ответ дан Whymarrh 19 August 2018 в 01:25
поделиться
  • 1
    Стоит отметить, что \ w, по крайней мере, в Java, соответствует _, а также шестнадцатеричные цифры. Замена \ w на \ p {XDigit} может быть более подходящей, так как это класс POSIX, определенный для соответствия шестнадцатеричных цифр. Это может сломаться при использовании других кодировок Unicode tho. – oconnor0 7 March 2011 в 22:41
  • 2
    @oconnor \w обычно означает «символы слова». Он будет соответствовать гораздо больше, чем шестнадцатеричные цифры. Ваше решение намного лучше. Или, для совместимости / удобочитаемости, вы можете использовать [a-f0-9] – exhuma 25 September 2011 в 10:23
  • 3
    Вот строка, которая выглядит как регулярное выражение и соответствует этим шаблонам, но является недопустимым регулярным выражением: 2wtu37k5-q174-4418-2cu2-276e4j82sv19 – OleTraveler 1 December 2016 в 20:37
  • 4
    @OleTraveler неправда, работает как шарм. import re def valid_uuid(uuid): regex = re.compile('[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12}', re.I) match = regex.match(uuid) return bool(match) valid_uuid('2wtu37k5-q174-4418-2cu2-276e4j82sv19') – Tom Wojcik 1 December 2017 в 10:25
  • 5
    @tom Эта строка (2wt ...) является недопустимым UUID, но шаблон, указанный в этом ответе, соответствует той строке, которая ложно указывает, что это действительный UUID. Слишком плохо, я не помню, почему UUID недействителен. – OleTraveler 2 December 2017 в 16:01
Другие вопросы по тегам:

Похожие вопросы: