Як зіставити цілий рядок із регулярним виразом?


82

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

Наприклад, якщо я шукаю фільми з назвою "Червоний Жовтень", я хочу лише відповідати саме тому заголовку (не враховуючи регістр), але не збігатись із заголовками, як "Полювання на Червоний Жовтень". Не зовсім впевнений, що знаю, як це зробити. Хтось знає?

Дякую!


1
Навіщо вам регулярний вираз для чогось, на що простий string.Containsбуде працювати?
Оді

1
Причина, по якій мені потрібно використовувати регулярний вираз, полягає в тому, що я використовую його для пошуку в MongoDB, і мені потрібно, щоб він не враховував регістр, що можна зробити лише за допомогою регулярного виразу
Micah

Чому б не перетворити (на льоту) дані db у малі та користувацькі рядки нижнього регістру для пошуку?
greenoldman

1
@macias Я не погоджуюся з тим, що це був би кращий варіант, але, на жаль, моя нинішня ситуація цього не дозволяє.
Михей

FYI, якщо не вимагає використання регулярних виразів, просто намагаюся порівняти два рядки без урахування регістру, можна просто зробитиstring1.Equals(string2, StringComparison.OrdinalIgnoreCase);
ToolmakerSteve

Відповіді:


111

Спробуйте наступний регулярний вираз:

^Red October$

За замовчуванням регулярні вирази чутливі до регістру. У ^Зазначає початок тексту відповідності і $кінця.


1
FYI, варто згадати, що, щоб зробити його чутливим до регістру, при створенні об’єкта регулярного виразу додайте другий параметр RegexOptions.IgnoreCase
ToolmakerSteve

Це не працює, якщо щось інше оточує цей рядок. Наприклад, якщо ви шукали "St", як у Street, але у вас є інші рядки в тому ж рядку, які також починаються на "St", такі як ім'я "Stirling", цей регулярний вираз не буде точно відповідати. Я не впевнений, що RegEx - правильна відповідь для цього сценарію, на жаль. Я збираюся продовжувати намагатися, хоча. Відповідь Тіма нижче хороша, але не всі двигуни це підтримують.
dislexicanaboko

Насправді, $це не завжди відповідає кінці рядка, \zце робить ( \Zце еквівалент у Python). Дивіться відповідь Тіма Піцкера . Це правда для JavaScript.
Wiktor Stribiżew

42

Як правило, і за замовчуванням, ^і $прив’язки - це хороший спосіб забезпечити відповідність регулярного виразу цілому рядку.

Однак кілька застережень:

Якщо у вас є чергування в своєму регулярному виразі, обов'язково укладіть регулярний вираз в не захоплюючи групи , перш ніж навколишній ^і $:

^foo|bar$

звичайно відрізняється від

^(?:foo|bar)$

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

Тому існує інший набір прив’язок, які гарантовано збігатимуться лише на початку / в кінці цілого рядка:

\A збіги на початку рядка.

\Z збіги в кінці рядка або перед остаточним розривом рядка.

\z збіги в самому кінці рядка.

Але не всі мови підтримують ці прив'язки, особливо JavaScript.


4
це найбільш корисна відповідь
Jeremy Danyow

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
}

2
ІМХО це МЕНШ простіше, ніж прийнята відповідь. Але це альтернатива.
ToolmakerSteve

Мені подобається ця відповідь, оскільки сам код показує передбачувану поведінку, а не модифікує регулярний вираз (що може бути менш зрозумілим для тих, хто кидає погляд на код із незначним розумінням регулярного виразу). Потенційна гикавка полягає в тому, що регулярний вираз можна записати так, щоб він міг відповідати цілому рядку або його частині, а функція Regex.Match повертає частковий збіг, хоча можливе повне збіг.
Джон Тойтс,

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, і мені це потрібно, щоб не враховувати регістр, що можна зробити лише за допомогою регулярного виразу.
Micah

-1

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.