Я даже не уверен, возможно ли это или нет, но вот что я хотел бы.
String: "NS306 FEBRUARY 20078/9/201013B1-9-1Low31 AUGUST 19870"
У меня есть текстовое поле, в котором я набираю параметры поиска, и они разделены пробелом. Из-за этого я хочу вернуть совпадение, если строка1 находится в строке, а затем строка2 находится в строке, ИЛИ строка2 находится в строке, а затем строка1 находится в строке. Мне все равно, в каком порядке расположены строки, но они ВСЕ (будет что-то больше 2) должны быть в строке.
Так, например, в предоставленной строке я бы хотел:
"FEB Low"
или
"Low FEB"
... чтобы вернуться как матч.
Я ' m ДЕЙСТВИТЕЛЬНО новичок в regex, прочитайте только некоторые уроки по здесь , но это было некоторое время назад, и мне нужно сделать это сегодня. В понедельник я начинаю новый проект, который намного важнее и не может быть отвлечен этим вопросом. Есть ли способ сделать это с помощью регулярных выражений, или мне нужно перебирать каждую часть поискового фильтра и переставлять порядок? Любая помощь очень ценится. . Благодаря
UPDATE: или мне нужно перебирать каждую часть поискового фильтра и переставлять порядок? Любая помощь очень ценится. . Благодаря
UPDATE: или мне нужно перебирать каждую часть поискового фильтра и переставлять порядок? Любая помощь очень ценится. . Благодаря
UPDATE: Причина, по которой я не хочу перебирать цикл и ищу наилучшую производительность, заключается в том, что, к сожалению, dataTable, который я использую, вызывает эту функцию при каждом нажатии клавиши, и я не хочу, чтобы она зависала.
UPDATE: Спасибо всем за вашу помощь, это было высоко оценено.
ОБНОВЛЕНИЕ КОДА:
В конечном счете, это то, с чем я столкнулся.
string sSearch = nvc["sSearch"].ToString().Replace(" ", ")(?=.*");
if (sSearch != null && sSearch != "")
{
Regex r = new Regex("^(?=.*" + sSearch + ").*$", RegexOptions.IgnoreCase);
_AdminList = _AdminList.Where(
delegate(IPB ipb)
{
//Concatenated all elements of IPB into a string
bool returnValue = r.IsMatch(strTest); //strTest is the concatenated string
return returnValue;
}).ToList();
}
}
Класс IPB содержит X элементов и ни одной таблицы на всем сайте. работаю над тем, чтобы столбцы были в одинаковом порядке. Поэтому мне нужно было искать любой заказ, и я не хотел писать много кода для этого. Здесь были и другие хорошие идеи, но я знаю, что моему боссу действительно нравится Regex (проповедует их), и поэтому я подумал, что было бы лучше, если бы я пошел с этим сейчас. Если по какой-либо причине производительность сайта снизится (интранет-сайт), я попробую другой путь. Спасибо всем.
Вы можете использовать (?=...)
положительный lookahead; он утверждает, что данный шаблон может быть найден. Вы встанете на якорь в начале строки и по очереди, в любом порядке, будете искать совпадение каждого из ваших шаблонов.
Это будет выглядеть примерно так:
^(?=.*one)(?=.*two)(?=.*three).*$
Это будет соответствовать строке, содержащей "один"
, "два"
, "три"
, в любом порядке (как показано на rubular.com).
В зависимости от контекста, вы можете захотеть поставить якорь на \A
и \Z
, и использовать однострочный режим, чтобы точка совпадала со всем.
Это не самое эффективное решение проблемы. Лучшим решением было бы разобрать слова во входных данных и поместить их в эффективное представление множества и т.д.
Допустим, мы хотим, чтобы наш пароль:
Тогда мы можем написать regex вроде этого:
^(?=.{8,15}$)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*]).*$
\__________/\_________/\_________/\_________/\______________/
length upper lower digit symbol
Я думаю, что на сегодня наиболее целесообразно будет ввести string.Split ('')
условия поиска и затем перебрать результаты, подтверждающие, что sourceString. Содержит (searchTerm)
var source = @"NS306 FEBRUARY 20078/9/201013B1-9-1Low31 AUGUST 19870".ToLowerInvariant();
var search = "FEB Low";
var terms = search.Split(' ');
bool all_match = !terms.Any(term => !(source.Contains(term.ToLowerInvariant())));
Обратите внимание, что мы используем Any ()
для установки короткого замыкания, поэтому, если первое условие не соответствует, мы пропускаем проверку второго, третьего и т. Д.
Это не лучший вариант использования RegEx. Манипуляции со строками, необходимые для того, чтобы взять произвольное количество строк поиска и преобразовать их в шаблон, почти наверняка сводят на нет преимущество в производительности сопоставления шаблона с механизмом RegEx, хотя это может варьироваться в зависимости от того, с чем вы сопоставляете.
В некоторых комментариях вы указали, что хотите избежать цикла, но RegEx не является однопроходным решением. Нетрудно создать ужасно неэффективный поиск, повторяющий и пошаговый по символам, как, например, печально известный катастрофический поиск с возвратом , где очень простое сопоставление требует тысяч шагов, чтобы вернуть false
.
var text = @"NS306Low FEBRUARY 2FEB0078/9/201013B1-9-1Low31 AUGUST 19870";
var matches = Regex.Matches(text, @"(FEB)|(Low)");
foreach (Match match in matches)
{
Console.WriteLine(match.Value);
}
Output:
Low
FEB
FEB
Low
Для начала.
Используйте string.Split (). Он вернет массив подстрок, которые повторно разделены указанной строкой / символом. Код будет выглядеть примерно так.
int maximumSize = 100;
string myString = "NS306 ФЕВРАЛЬ 20078/9 / 201013B1-9-1Low31 АВГУСТА 19870";
string [] IndividualString = myString.Split ('', maximumSize);
Для получения дополнительной информации http://msdn.microsoft.com/en-us/library/system.string.split.aspx
Изменить:
Если вы действительно хотите использовать регулярные выражения, этот шаблон будет работать.
[^] *
И вы просто будете использовать Regex.Matches ();
Код будет примерно таким:
string myString = "NS306 ФЕВРАЛЬ 20078/9 / 201013B1-9-1Low31 АВГУСТА 19870";
шаблон строки = "[^] *";
Regex rgx = новое регулярное выражение (шаблон);
foreach (Соответствует совпадению в совпадениях (ах))
{
// что-то делаем с match.value
}
Вам не нужно проверять каждую перестановку, просто разделите поиск на несколько частей «FEB» и «Low» и убедитесь, что каждая часть совпадает. Это будет намного проще, чем пытаться придумать регулярное выражение, которое соответствовало бы всему за один раз (что, я уверен, теоретически возможно, но, вероятно, не практично в действительности).
Почему бы просто не выполнить простую проверку текста, поскольку порядок не имеет значения?
string test = "NS306 FEBRUARY 20078/9/201013B1-9-1Low31 AUGUST 19870";
test = test.ToUpper();
bool match = ((test.IndexOf("FEB") >= 0) && (test.IndexOf("LOW") >= 0));
Это нужно для использования регулярного выражения?