Если вы хотите, чтобы соответствовать перестановка множества элементов, вы может использовать комбинацию обратных ссылок и нулевую ширину отрицательное согласование вперед.
Допустим, вы хотите, чтобы соответствовать любой из этих шести строк:
123-abc-456-def-789-ghi-0AB
123-abc-456-ghi-789-def-0AB
123-def-456-abc-789-ghi-0AB
123-def-456-ghi-789-abc-0AB
123-ghi-456-abc-789-def-0AB
123-ghi-456-def-789-abc-0AB
Вы можете сделать это с помощью следующих регулярных выражений:
/123-(abc|def|ghi)-456-(?!\1)(abc|def|ghi)-789-(?!\1|\2)(abc|def|ghi)-0AB/
Обратные ссылки (\1
, \2
), пусть вас обратитесь к вашим предыдущим совпадениям, а нулевой шириной в прямом направлении ((?!...)
) позволяет свести на нет позиционное совпадение, если не совпадают, если содержит совпадения в этом положении. Сочетание двух элементов гарантирует, что ваш матч является законной перестановкой данных элементов, причем каждая возможность возникает только один раз.
Так, например, в Ruby:
input = <<LINES
123-abc-456-abc-789-abc-0AB
123-abc-456-abc-789-def-0AB
123-abc-456-abc-789-ghi-0AB
123-abc-456-def-789-abc-0AB
123-abc-456-def-789-def-0AB
123-abc-456-def-789-ghi-0AB
123-abc-456-ghi-789-abc-0AB
123-abc-456-ghi-789-def-0AB
123-abc-456-ghi-789-ghi-0AB
123-def-456-abc-789-abc-0AB
123-def-456-abc-789-def-0AB
123-def-456-abc-789-ghi-0AB
123-def-456-def-789-abc-0AB
123-def-456-def-789-def-0AB
123-def-456-def-789-ghi-0AB
123-def-456-ghi-789-abc-0AB
123-def-456-ghi-789-def-0AB
123-def-456-ghi-789-ghi-0AB
123-ghi-456-abc-789-abc-0AB
123-ghi-456-abc-789-def-0AB
123-ghi-456-abc-789-ghi-0AB
123-ghi-456-def-789-abc-0AB
123-ghi-456-def-789-def-0AB
123-ghi-456-def-789-ghi-0AB
123-ghi-456-ghi-789-abc-0AB
123-ghi-456-ghi-789-def-0AB
123-ghi-456-ghi-789-ghi-0AB
LINES
# outputs only the permutations
puts input.grep(/123-(abc|def|ghi)-456-(?!\1)(abc|def|ghi)-789-(?!\1|\2)(abc|def|ghi)-0AB/)
Для перестановки из пяти элементов, было бы:
/1-(abc|def|ghi|jkl|mno)-
2-(?!\1)(abc|def|ghi|jkl|mno)-
3-(?!\1|\2)(abc|def|ghi|jkl|mno)-
4-(?!\1|\2|\3)(abc|def|ghi|jkl|mno)-
5-(?!\1|\2|\3|\4)(abc|def|ghi|jkl|mno)-6/x
Для примера, регулярное выражение будет
/<a href="home.php" (class="link"|title="Home") (?!\1)(class="link"|title="Home")>Home<\/a>/
Мне нравится @Josh Bush ответ ниже, так как это то, что работает для меня сейчас, когда я наткнулся на это – Rick
Нет, вы не можете этого сделать. Это одна из причин, по которым вы ** не используете регулярные выражения для анализа HTML (или XML). Используйте подходящий модуль синтаксического анализа HTML. ** Вы не можете надежно проанализировать HTML с регулярными выражениями, и вы столкнетесь с печалью и разочарованием в будущем. Как только HTML изменится с ваших ожиданий, ваш код будет сломан. См. Http: // htmlparsing.com/php для примеров того, как правильно анализировать HTML с PHP-модулями, которые уже были написаны, протестированы и отлажены. –
Это одна из многих причин, по которым регулярные выражения не подходят для синтаксического анализа XML или HTML. –