C #: encontrar ocorrências de um texto dentro de uma string
Pergunta
Suponha que eu tinha a string "1 e 2 e 3 ou 4", e deseja criar uma matriz de strings que contém todos os substrings "AND" ou "OR", em ordem, encontrada dentro da string.
Assim, a seqüência acima retornaria uma matriz de cadeia de { "E", "E", "OU"}.
O que seria uma maneira inteligente de escrever isso?
EDIT: Usando C # 2,0 +,
string rule = "1 AND 2 AND 3 OR 4";
string pattern = "(AND|OR)";
string[] conditions = Regex.Split(rule, pattern);
dá-me { "1", "E", "2", "E", "3", "OU", "4"}, que não é bem o que eu estou atrás. Como posso reduzir isso para os operadores AND e OR única?
Solução
Este regex (.NET) parece fazer o que quiser. Você está procurando os jogos (múltiplos) no grupo de index = 1:
.*?((AND)|(OR))*.*?
Editar Eu testei o seguinte e parece fazer o que quiser. É mais linhas do que eu gostaria, mas se aproxima a tarefa de forma puramente regex (que IMHO é o que você deve fazer):
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));
Outras dicas
Seu provavelmente à procura de um tokeniser ou Lexer, ter um olhar para o seguinte artigo:
Uma vez que você sabe exatamente o substring que você está procurando ... por que não usar IndexOf (substr, iOffset) para saber o número de ocorrências (circular até que ele retorna -1) ??
Dependendo da complexidade de sua tarefa, ele poderia ser mais simples / mais rápido do que usando expressões regulares (desde que você não está combinando padrões).
string rule = "1 AND 2 AND 3 OR 4";
string pattern = "(AND|OR)";
MatchCollection conditions = Regex.Matches(rule, pattern);
Use Match.Value para obter a string.
Aqui está uma maneira pateta que eu vim com:
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;