Я безнадежен с регулярным выражением (C#), поэтому я был бы признателен за помощь:
В основном мне нужно проанализировать текст, и мне нужно найти в тексте следующую информацию:
Образец текста:
KeywordB: *** TextToFind * остальное не имеет значения, но ** KeywordB:Текст ToFindB, а затем еще текст.
Мне нужно найти слово (а) после определенного ключевого слова, которое может оканчиваться на «:».
[ОБНОВИТЬ]
Спасибо, Эндрю и Алан: извините за повторное открытие вопроса, но в этом регулярном выражении отсутствует довольно важная вещь. Как я писал в своем последнем комментарии, возможно ли иметь переменную (сколько слов искать, в зависимости от ключевого слова) как часть регулярного выражения?
Или: у меня может быть другое регулярное выражение для каждого ключевого слова (это будет только ручная работа). Но все еще не знаю, как иметь константу "слова для поиска" внутри регулярного выражения.





/KeywordB\: (\w)/
Это соответствует любому слову, которое следует после вашего ключевого слова. Поскольку вы не упомянули терминатор, я предположил, что вам нужно только слово рядом с ключевым словом.
Это не похоже на регулярное выражение C#, а скорее похоже на perl.
@ Андрей, ты имеешь в виду, потому что он заключен в косую черту? В этом нет ничего страшного; просто замените их кавычками. В самом регулярном выражении нет ничего, что могло бы вызвать сбои в C#.
@Tiago, настоящая проблема в том, что \w соответствует только одному символу; вы должны изменить его на \w+. Кроме того, я считаю, что Flo использовал только «KeywordB» в качестве примера, и вам также следует заменить его на \w+.
Основное регулярное выражение таково:
var pattern = @"KeywordB:\s*(\w*)";
\s* = any number of spaces
\w* = 0 or more word characters (non-space, basically)
() = make a group, so you can extract the part that matched
var pattern = @"KeywordB:\s*(\w*)";
var test = @"KeywordB: TextToFind";
var match = Regex.Match(test, pattern);
if (match.Success) {
Console.Write("Value found = {0}", match.Groups[1]);
}
Если у вас более одного из них в строке, вы можете использовать это:
var test = @"KeywordB: TextToFind KeyWordF: MoreText";
var matches = Regex.Matches(test, @"(?:\s*(?<key>\w*):\s?(?<value>\w*))");
foreach (Match f in matches ) {
Console.WriteLine("Keyword '{0}' = '{1}'", f.Groups["key"], f.Groups["value"]);
}
Также ознакомьтесь с дизайнером регулярных выражений здесь: http://www.radsoftware.com.au/. Это бесплатно, и я постоянно им пользуюсь. Он отлично работает с выражениями-прототипами. Вам нужно изменить интерфейс для основной работы, но после этого это легко.
(к сведению) "@" перед строками означает, что \ больше не означает что-то особенное, поэтому вы можете ввести @ "c: \ fun.txt" вместо "c: \ fun.txt"
Великолепно, именно то, что я искал. Большое спасибо!
И еще одно: в некоторых случаях значение может быть 2 слова, а не одно слово. Какие-либо предложения?
Как регулярное выражение должно знать, что оно должно соответствовать двум словам, а не одному?
@ Андрей, ты понимаешь, что почти все в этом регулярном выражении необязательно? По закону он может соответствовать просто двоеточию. Вам следует заменить \w* на \w+. Кроме того, я не вижу необходимости заключать все это в скобки, ни для этого \s* в начале.
@Alan Итак, нет способа указать регулярному выражению не только "получить" первый, но и 2-х секундный вирд, которые разделены пробелом?
Да, он мог бы быть более полным, более надежным и т. д., Но это был не совсем рабочий код :) Я обновлю его. Кроме того, единственный хороший способ сопоставить более одного слова - это убедиться, что ":" стоит сразу после ключевого слова.
@Flo, если строка - «KeywordB: word1 word2 more text», как узнать, должно ли регулярное выражение соответствовать «word2»? Есть ли что-то во втором слове, что отличает его от следующего текста?
Алан, возможно ли иметь переменную (сколько слов искать, в зависимости от ключевого слова) как часть регулярного выражения? Или: я мог бы иметь другое регулярное выражение для каждого ключевого слова (это будет только ручная работа). Но все еще не знаю, как иметь константу "слова для поиска" внутри регулярного выражения.
Черт, это НАМНОГО сложнее, чем я думал ... правда. Я делал что-то подобное раньше с регулярным выражением. Возможно, вам будет лучше просто поискать что-то вроде шаблона «ключ:», а затем извлечь все после этого и до следующего возникновения.
Сообщите мне, если я должен удалить старый пост, но, возможно, кто-то захочет его прочитать.
Способ "искать слова" внутри регулярного выражения выглядит следующим образом:
regex = @"(Key1|Key2|Key3|LastName|FirstName|Etc):"
То, что вы делаете, вероятно, не стоит усилий в регулярном выражении, хотя наверное можно выполнить так, как вы хотите (хотя требования все еще не на 100% ясны). Это предполагает ожидание следующего матча и остановку на этом этапе.
Вот перезапись как регулярное выражение + обычный функциональный код, который должен помочь. Он не заботится о пробелах, поэтому, если вы попросите «Key2», как показано ниже, он отделит его от значения.
string[] keys = {"Key1", "Key2", "Key3"};
string source = "Key1:Value1Key2: ValueAnd A: To Test Key3: Something";
FindKeys(keys, source);
private void FindKeys(IEnumerable<string> keywords, string source) {
var found = new Dictionary<string, string>(10);
var keys = string.Join("|", keywords.ToArray());
var matches = Regex.Matches(source, @"(?<key>" + keys + "):",
RegexOptions.IgnoreCase);
foreach (Match m in matches) {
var key = m.Groups["key"].ToString();
var start = m.Index + m.Length;
var nx = m.NextMatch();
var end = (nx.Success ? nx.Index : source.Length);
found.Add(key, source.Substring(start, end - start));
}
foreach (var n in found) {
Console.WriteLine("Key = {0}, Value = {1}", n.Key, n.Value);
}
}
И результат этого:
Key=Key1, Value=Value1
Key=Key2, Value= ValueAnd A: To Test
Key=Key3, Value= Something
@ Андрей, милый! Пробел «Ключ 2: Значение и A:» в значении был именно в этом и заключалась проблема. Благодарность!
Рад, что смог помочь. Я все еще пытаюсь найти хороший способ чистого регулярного выражения для этого, возможно, с помощью простого цикла, но пока я могу получить только 70% "правильности".
Жду 100% :-)
спасибо за хороший ответ, почти то, что я ищу, однако как изменить решение, чтобы вернуть 1.1, 1.2, 1.3, если исходная строка: '' Key1: (1.1) Key2: (1.2) And A: To Test Key3: (1.3) бла-бла-бла ''. После применения этого решения к моей строке я беру каждую и разделяю значения на основе круглых скобок. Но разве нет лучшего решения для чистого регулярного выражения?
Синтаксис регулярных выражений немного отличается, если вы используете технологию, ориентированную на Linux или технологию, ориентированную на Microsoft, поэтому вы можете пометить, с какой из них вы работаете.