Что касается регулярных выражений PCRE, в чем разница между [abc] и (a | b | c)?Разница между [abc] и (a | b | c)
ответ
Узоры в вашем вопросе совпадают с тем же текстом. С точки зрения реализации они соответствуют различным автоматам и побочным эффектам (, т. Е., независимо от того, захватывают ли они подстроки).
В комментарии ниже, Garrett Albright указывает на тонкое различие. В то время как (.|\n)
соответствует любому персонажу, [.\n]
соответствует литеральной точке или символу новой строки. Хотя точка больше не является специальной внутри класса символов, другие символы, такие как -
, ^
и ]
, а также такие последовательности, как [:lower:]
, принимают специальные значения внутри класса символов. Уход необходим для сохранения специальной семантики из одного контекста в другой, но иногда это возможно, например, в случае \1
как архаичный способ написания $1
вне класса персонажа. Внутри класса символов \1
всегда соответствует символу SOH.
Классы символов ([...]
) оптимизированы для соответствия одному из некоторого набора символов, а альтернативы (x|y
) позволяют использовать более общий выбор различной длины. Вы будете видеть лучшую производительность, если будете придерживаться этих принципов дизайна. Реализационные преобразования преобразуют исходный код, например /[abc]/
, в автоматы с конечным состоянием, обычно NFAs. То, что мы считаем двигателями регулярных выражений, - это более или менее бухгалтеры, которые помогают выполнять эти целевые государственные машины. Достаточно умный компилятор регулярных выражений будет генерировать одинаковый машинный код для эквивалентных регулярных выражений, но это сложно и дорого в общем случае из-за lurking exponential complexity.
Для ознакомления с теорией за регулярными выражениями читайте “How Regexes Work” от Марка Домина. Для более глубокого изучения рассмотрим An Introduction to Formal Languages and Automata от Peter Linz.
Когда вы будете использовать один над другим? Что вы подразумеваете под «они соответствуют различным автоматам и захвату подстроки»? Спасибо – user1032531
Если a, b и c - это просто буквы, конечно (как я думаю, это подразумевается). Очевидно, что если они могут стоять за слова, это совершенно другая семантика. – kratenko
Я обнаружил, что иногда вариант квадратной скобки не работает должным образом для забавных символов, таких как '\ n' или' \ r'. Например, чтобы уловить весь текст между FOO и BAR, включая символы новой строки, '/ FOO ((. | \ N) +) BAR /' работает, тогда как '/ FOO ([. \ N] +) BAR /' не делает. Однако это может быть специфично для реализации. Я нашел другие отличия, которые я не могу вспомнить с головы.Во всяком случае, как правило, я попытаюсь использовать '[ab]' first, так как это более читаемо, а затем дайте '(a | b)' попытку, если что-то не работает. –
(после прочтения ответа Грега): Если они оцениваются по-разному, они должны зависеть от любой программы, к которой вы их кормите. Выберите, что вы пытаетесь проверить. Вы хотите проверить пул допустимых символов или хотите проверить значения. - Иногда это может показаться одним и тем же, но за этим может быть другое намерение. Затем выберите то, что отражает ваши намерения.
Форма, использующая квадратные скобки, намного быстрее с помощью PCRE, особенно если включена компиляция JIT. Он просто проверяет бит в битете, а другой перечитывает символ для каждой альтернативы. Я думал об оптимизации, которая бы обнаруживала такие случаи, поскольку многие не знают, что классы символов могут использоваться внутри квадратных скобок, и они используют ([a-z] | \ s) + вместо [a-z \ s] +.
- 1. Есть ли разница между `from abc import a, b` и` from abc import (a, b) `?
- 2. Разница между a = b и b = a?
- 3. Какая разница между a == b и (a & b) == b
- 4. Разница между a + b и a .__ add __ (b)
- 5. Perl speed: разница между $ a = $ a. $ B и $ a. = $ B
- 6. Разница между || a = b и a = a || b в рубине?
- 7. Разница между a - = b и a = a - b в Python
- 8. В чем разница между a = a + b и a + = b?
- 9. Разница между a + = b и a = a + b в Java
- 10. разница между $ [a-b] и $ ((a-b)) в bash
- 11. В чем разница между * (a + b) и (* a + b)
- 12. В чем разница между «numpy.add (a, b)» и «a + b»?
- 13. В чем разница между ['[a, a, a]', '[b, b, b]'] и [[a, a, a], [b, b, b]] в python?
- 14. Разница между копией/a и копией/b
- 15. В чем разница между [:] = b и a = b [:]
- 16. В чем разница между '(a b c) и (список' a 'b' c)?
- 17. Указатели на указатели: Разница между * a = b-> c и a = & b-> c
- 18. В чем разница между x = функцией (a, b, c) {} и функцией x (a, b, c) {}?
- 19. Какая разница между «abc» и {«abc»} в C?
- 20. Почему «abc'.split (/ (a | b | c) /) дает a, b, c, AND пустые строки в Javascript?
- 21. Различия между * a = b и a = & b?
- 22. Разница между $ a = & $ b, $ a = $ b и $ a = clone $ b в PHP OOP
- 23. Разница между sort(), sort (function (a, b) {return a-b;}); и sort (function (a, b) {...})
- 24. Неопределенная ссылка - должна ли быть разница между `a = -b;` и `a = -1 * b;` и `a = 0-b` в C++?
- 25. разница между "класса А, класса B" и "класса A :: B"
- 26. В чем разница между // b и int (a/b)?
- 27. C В чем разница между unsigned int (a)^unsigned int (b) и unsigned int (a^b)?
- 28. C++: Может ли макрос расширять «abc» в «a», «b», «c»?
- 29. Разница между a + = 1 и a = a + 1 в C#
- 30. В чем разница между b и c?
[Использование альтернативного или символьного класса для односимвольного совпадения?] (Http://stackoverflow.com/questions/4724588/using-alternation-or-character-class-for-single-character-matching) имеет несколько интересных ответы. – stema
Это другое сообщение было полезно. Thanks – user1032531