(Это продолжение разговора от комментариев к ответу Эвана.)
Вот что происходит, когда применяется ваше (исправленное) регулярное выражение: Во-первых, .+
соответствует всей строке. Затем он возвращается, отдавая большинство символов, которые ему соответствуют, пока не достигнет точки, где B=
может совпадать. Затем (.+?)
сопоставляет (и захватывает) все, что видит, пока следующая часть, точка с запятой, не сможет совпадать. Затем финал .+
сожирает оставшихся персонажей.
Все, что вас действительно интересует, это "B =" и ";" и что между ними, так зачем сопоставлять остальную часть строки? Единственная причина, по которой вы должны это сделать, - это заменить всю строку содержимым группы захвата. Но зачем делать это, если вы можете получить доступ к содержимому группы напрямую? Вот демонстрация (на Java, потому что я не могу сказать, какой язык вы используете):
String s = "A=abc;B=def_3%^123+-;C=123;";
Pattern p = Pattern.compile("B=(.*?);");
Matcher m = p.matcher(s);
if (m.find())
{
System.out.println(m.group(1));
}
Почему «заменить», когда «найти» гораздо проще? Возможно, потому что ваш API делает это проще; Вот почему мы делаем это на Java. Java имеет несколько удобных для регулярных выражений методов удобства в своем классе String: replaceAll()
, replaceFirst()
, split()
и matches()
(который возвращает true
, если регулярное выражение соответствует целом строке) но не find()
. И нет удобного способа доступа к группам захвата. Мы не можем сравниться с элегантностью однострочников Perl:
print $1 if 'A=abc;B=def_3%^123+-;C=123;' =~ /B=(.*?);/;
... поэтому мы довольствуемся такими взломами:
System.out.println("A=abc;B=def_3%^123+-;C=123;"
.replaceFirst(".+B=(.*?);.+", "$1"));
Просто чтобы прояснить, я не говорю, чтобы не использовать эти хаки, или что с ответом Эвана что-то не так - нет. Я просто думаю, что мы должны понимать , почему мы их используем, и какие компромиссы мы делаем, когда делаем.