C#:поиск экземпляров строки внутри строки
Вопрос
Предположим, у меня есть строка "1 И 2 И 3 ИЛИ 4", и я хочу создать массив строк, содержащий все подстроки "И" или "ИЛИ" по порядку, найденные в строке.
Таким образом, приведенная выше строка вернет массив строк {"И", "И", "ИЛИ"}.
Какой был бы разумный способ написать это?
Редактировать:Использование C # 2.0+,
string rule = "1 AND 2 AND 3 OR 4";
string pattern = "(AND|OR)";
string[] conditions = Regex.Split(rule, pattern);
дает мне {"1", "И", "2", "И", "3", "ИЛИ", "4"}, что не совсем то, что мне нужно.Как я могу свести это только к ANDs и ORS?
Решение
Это регулярное выражение (.NET), кажется, делает то, что вы хотите.Вы ищете совпадения (множественные) в группе с индексом =1:
.*?((AND)|(OR))*.*?
Редактировать Я протестировал следующее, и, похоже, оно делает то, что вы хотите.В нем больше строк, чем мне бы хотелось, но он подходит к задаче чисто в стиле регулярных выражений (что, ИМХО, вам и следует делать).:
string text = "1 AND 2 AND 3 OR 4";
string pattern = @"AND|OR";
Regex r = new Regex(pattern, RegexOptions.IgnoreCase);
Match m = r.Match(text);
ArrayList results = new ArrayList();
while (m.Success)
{
results.Add(m.Groups[0].Value);
m = m.NextMatch();
}
string[] matchesStringArray = (string[])results.ToArray(typeof(string));
Другие советы
Возможно, вы ищете токенизатор или лексер, взгляните на следующую статью:
Поскольку вы знаете точную подстроку, которую ищете...почему бы просто не использовать indexOf(substr, iOffset) Индекс (substr, iOffset) чтобы узнать количество вхождений (цикл до тех пор, пока он не вернет -1)??
В зависимости от сложности вашей задачи это может быть проще / быстрее, чем использование регулярных выражений (поскольку вы не сопоставляете шаблоны).
string rule = "1 AND 2 AND 3 OR 4";
string pattern = "(AND|OR)";
MatchCollection conditions = Regex.Matches(rule, pattern);
Используйте Match.Значение, чтобы получить строку.
Вот дурацкий способ, который я придумал:
string rule = "1 AND 2 AND 3 OR 4";
List<string> andsOrs = new List<string>();
string[] split = rule.Split();
for (int i = 0; i < split.Length; i++)
{
if (split[i] == "AND" || split[i] == "OR")
{
andsOrs.Add(split[i]);
}
}
string[] conditions = andsOrs.ToArray();
return conditions;