Что такое регулярное выражение?
Я знаю, что этот вопрос кажется глупым, но это не так. Я имею в виду, что это точно. У меня есть хорошее понимание проблемы синтаксического анализа. Я знаю BNF/EBNF, я написал грамматику для анализа простых контекстно-свободных языков в одном из моих курсов в колледже. Я никогда раньше не встречал регулярных выражений! Единственное, что я помню об этом, это то, что контекстно-свободная грамматика может делать все, что может делать регулярное выражение.
Также полезно ли использовать обычное кодирование для синтаксического анализа строк? Простой пример был бы полезен.
Ответы
Ответ 1
Регулярные выражения впервые появились в теории математики и автоматов. Регулярное выражение - это просто то, что определяет обычный язык. Не останавливаясь на том, что означает "обычный", подумайте о таком языке:
- Язык состоит из строк. Английский язык - это, например, язык, и он состоит из строк.
- Эти строки состоят из символов, называемых алфавитом. Таким образом, строка представляет собой просто конкатенацию символов из алфавита.
Таким образом, у вас может быть строка (которая, помните, просто конкатенация символов), которая не является частью данного языка. Или это может быть на языке.
Итак, скажем, у вас есть алфавит из 2-х символов: "0" и "1". И скажем, вы хотите создать язык, используя символы в этом алфавите. Вы можете создать следующее правило: "Чтобы строка была на моем языке, она должна содержать только 0 и 1".
Итак, эти строки находятся на вашем языке:
- 0
- 1
- 01
- 11001101
- ... и т.д.
Это не будет на вашем языке:
Это довольно простой язык. Как об этом: "На моем языке каждая строка [аналогичная действительному" слову "на английском языке] должна быть с 0, а затем может следовать любое число 0 или 1"
Это на языке:
- 0111111
- 0000000
- 0101010110001
Это не:
Вместо того, чтобы определять язык с использованием слов - и эти языки могут стать очень сложными ( "1 за ним следует 2 0, за которым следует любая комбинация 1 и 0, заканчивающаяся на 1" ), мы пришли к этому синтаксису, называемому "регулярным выражения" для определения языка.
Первый язык:
(0|1)*
(0 или 1, повторяется бесконечно)
Следующий: 0(0|1)*
(0, за которым следует любое число 0 и 1).
Так что давайте думать о программировании сейчас. Когда вы создаете регулярное выражение, вы говорите "Посмотрите на этот текст. Верните мне строки, соответствующие этому шаблону". Это действительно говорит: "Я определил язык. Верните мне все строки в этом документе, которые находятся на моем языке".
Поэтому, когда вы создаете "регулярное выражение", вы на самом деле определяете обычный язык, который является математическим понятием. (На самом деле Perl-подобное регулярное выражение определяет "нерегулярные" языки, но это отдельная проблема.)
Изучая синтаксис регулярного выражения, вы изучаете все аспекты создания языка, чтобы потом вы могли видеть, является ли данная строка "in" на языке. Таким образом, обычно люди говорят, что регулярное выражение предназначено для сопоставления шаблонов - это в основном то, что вы делаете, когда смотрите на шаблон и видите, соответствует ли он правилам для вашего языка.
(это было давно, это вообще ответ на ваш вопрос?)
Ответ 2
Регулярное выражение является специализированным языком для сопоставления шаблонов. Они используются во многих текстовых редакторах и языках программирования для сопоставления строк.
Вы можете делать много более сложных вещей с помощью регулярных выражений. Там великая книга О'Рейли по этому вопросу и многочисленные примеры в Интернете.
То, что вы не можете делать с регулярными выражениями, - это правильный анализ, потому что регулярные выражения не являются достаточным языком для кодирования грамматики. Они специализируются на сопоставлении шаблонов, и если вы попытаетесь использовать их для разбора чего-то вроде XML, у вас наверняка возникнут проблемы в будущем. Более конкретно, вы не можете разбирать произвольно вложенные рекурсивные структуры, используя регулярные выражения. Простой пример проблемы, которую регулярное выражение не может решить хорошо, - это набор вложенных фигурных скобок, например, в C:
int main() {
void func() {
}
}
Вы можете заставить регулярные выражения решить это до определенной точки, но требования к памяти для этого возрастают сколь угодно большим по мере увеличения числа фигурных скобок. Если вас интересует более подробно, прочитайте этот другой вопрос StackOverflow о том, почему такая конструкция трудно анализировать с помощью регулярных выражений:
Можно ли использовать регулярные выражения для соответствия вложенным шаблонам?
Различные языки реализуют регулярные выражения по-разному, но реализация Perl очень популярна. Семейство регулярных выражений, совместимых с Perl, называется PCRE, или P erl- C ompatible R egular E Xpressions. Вот пример в Perl регулярного выражения, которое может соответствовать целым числам:
#!/usr/bin/perl
use strict;
use warnings;
match_string( "one-two" );
match_string( "1-2" );
sub match_string {
my $string = shift;
if ( $string =~ /(\d+)/ ) {
print "$string matches!\n";
print "matched: ", $1, "\n";
} else {
print "$string doesn't match!\n";
}
}
$ perl test.pl
one-two doesn't match!
1-2 matches!
matched: 1
В этом примере регулярное выражение соответствует одному или нескольким примерам цифры. Здесь строка:
if ( $string =~ /(\d+)/ ) {
Способ чтения:
- внутри условного выражения строка сопоставляется с регулярным выражением между /.s
- символ \d преобразуется в цифру, 0-9.
- + означает "один или несколько раз".
- parens() означает захват этого совпадения и помещает его в специальную переменную. Поскольку это первый матч, он помещается в $1.
В некоторых языках (например, Perl) вы также можете использовать регулярные выражения для выполнения подстановок, например:
substitute_string( "one-two" );
substitute_string( "1-2" );
sub substitute_string {
my $string = shift;
print "before: ", $string, "\n";
$string =~ s/1/one/g;
$string =~ s/2/two/g;
print "after: ", $string, "\n";
}
$ perl test.pl
before: one-two
after: one-two
before: 1-2
after: one-two
Надеюсь, этого достаточно, чтобы вы начали!
Ответ 3
Другие люди рассказали, что такое регулярное выражение, и для чего его можно использовать, поэтому я не буду перефразировать предыдущие ответы. Однако, если вам интересно узнать о синтаксисе регулярных выражений (например, как создать регулярное выражение), посмотрите Tutorial раздел в regular-expression.info; это, вероятно, самый независимый ресурс синтаксиса регулярных выражений в Интернете.