Как сопоставить целую строку с регулярным выражением?

82

Мне нужно регулярное выражение, которое будет находить только совпадения, в которых вся строка соответствует моему запросу.

Например, если я выполняю поиск фильмов с названием «Красный октябрь», я хочу найти совпадение только по этому точному названию (без учета регистра), но не совпадать с такими названиями, как «Охота за красным октябрем». Не совсем уверен, что знаю, как это сделать. Кто-нибудь знает?

Благодаря!

Мика
источник
1
Зачем вам нужно регулярное выражение для чего-то, для чего string.Containsбудет работать простое ?
Одед
1
Причина, по которой мне нужно использовать регулярное выражение, заключается в том, что я использую его для поиска в MongoDB, и мне нужно, чтобы оно было нечувствительным к регистру, что можно сделать только с регулярным выражением
Мика
Почему бы не преобразовать (на лету) данные БД в строчные и пользовательские строчные строки для поиска?
greenoldman
1
@macias Я не возражаю, что это был бы лучший вариант, но, к сожалению, моя текущая ситуация не позволяет этого.
Micah
FYI, если не требует использования регулярных выражений, просто пытаюсь сравнить две строки без учета регистра, можно просто сделатьstring1.Equals(string2, StringComparison.OrdinalIgnoreCase);
ToolmakerSteve

Ответы:

111

Попробуйте следующее регулярное выражение:

^Red October$

По умолчанию регулярные выражения чувствительны к регистру. Знак ^отмечает начало и $конец совпадающего текста .

Питер ван Гинкель
источник
1
К вашему сведению, стоит упомянуть, что, чтобы сделать его нечувствительным к регистру, при создании объекта регулярного выражения добавьте второй параметр RegexOptions.IgnoreCase.
ToolmakerSteve
Это не сработает, если эту строку окружает что-то еще. Например, если вы искали «St», как в Street, но у вас есть другие строки в той же строке, которые также начинаются с «St», например имя «Stirling», это регулярное выражение не будет точно соответствовать. К сожалению, я не уверен, что RegEx - правильный ответ для этого сценария. Но я буду продолжать попытки. Ответ Тима ниже хорош, но не все движки поддерживают это.
dyslexicanaboko
На самом деле, $не всегда соответствует концу строки, соответствует \z( \Zэквивалент в Python). См . Ответ Тима Пицкера . Однако это верно для JavaScript.
Wiktor Stribiew
42

Как правило, и с настройками по умолчанию, ^и$ якоря - хороший способ убедиться, что регулярное выражение соответствует всей строке.

Однако есть несколько предостережений:

Если у вас есть чередование в вашем регулярном выражении, обязательно заключите ваше регулярное выражение в группу без захвата, прежде чем окружать его ^и $:

^foo|bar$

конечно отличается от

^(?:foo|bar)$

Кроме того, ^и $может иметь другое значение (начало / конец строки вместо начала / конца строки ), если установлены определенные параметры. В текстовых редакторах, поддерживающих регулярные выражения, это обычно поведение по умолчанию. В некоторых языках, особенно Ruby, это поведение даже нельзя отключить.

Следовательно, есть еще один набор якорей, которые гарантированно будут соответствовать только в начале / конце всей строки:

\A совпадает с началом строки.

\Z совпадает в конце строки или перед окончательным разрывом строки.

\z соответствует в самом конце строки.

Но не все языки поддерживают эти привязки, особенно JavaScript.

Тим Пицкер
источник
4
это самый полезный ответ
Джереми Даньоу
18

Используйте ^и $модификаторы для обозначения , где регулярное выражение шаблон сидит относительно начала и конца строки:

Regex.Match("Red October", "^Red October$"); // pass
Regex.Match("The Hunt for Red October", "^Red October$"); // fail
Тим Робинсон
источник
10

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

Самый простой способ:

var someString = "...";
var someRegex = "...";
var match = Regex.Match(someString , someRegex );
if(match.Success && match.Value.Length == someString.Length){
    //pass
} else {
    //fail
}
Zixav
источник
2
ИМХО это МЕНЬШЕ просто, чем принятый ответ. Но это альтернатива.
ToolmakerSteve
Мне нравится этот ответ, потому что сам код показывает предполагаемое поведение, а не изменяет регулярное выражение (что может быть менее понятно для тех, кто смотрит на код с небольшим пониманием регулярного выражения). Потенциальный сбой заключается в том, что регулярное выражение можно было бы написать так, чтобы оно могло соответствовать либо всей строке, либо ее части, при этом функция Regex.Match возвращает частичное совпадение, даже если полное совпадение возможно.
John Thoits
8

Вам нужно заключить свое регулярное выражение в ^(начало строки) и $(конец строки):

^Red October$
Антон Гоголев
источник
0

Извините, но это немного непонятно.

Из того, что я читал, вы хотите провести простое сравнение строк. Для этого вам не нужно регулярное выражение.

string myTest = "Red October";
bool isMatch = (myTest.ToLower() == "Red October".ToLower());
Console.WriteLine(isMatch);
isMatch = (myTest.ToLower() == "The Hunt for Red October".ToLower());
Дин Томас
источник
1
Причина, по которой мне нужно использовать регулярное выражение, заключается в том, что я использую его для поиска в MongoDB, и мне нужно, чтобы оно было нечувствительным к регистру, что можно сделать только с помощью регулярного выражения.
Мика
-1

Вы можете сделать это, как этот пример, если я хочу только один раз поймать букву минус a в строке, и это можно проверить с помощью myRegex.IsMatch ()

^ [^ e] [e] {1} [^ e] $

Винсент Рой
источник