Regex para combinar ARGB Cor (-44830298)
Pergunta
Eu estou tentando obter informações a cores que eu tenho armazenado em um arquivo de texto e, em seguida, usar essa cor como o forecolor para uma etiqueta. MAS, em tempo de execução quando eu clico no botão para fazê-lo, ele não me dar quaisquer mensagens de erro ou qualquer coisa. o código que eu tenho é abaixo:
MatchCollection lines = Regex.Matches(File.ReadAllText(Path), @"(.+?)\r\n""([^""]+)""\r\n(\d+),\s(\d+)\r\n([\w\s]*)\r\n(\d+\.\d+)""\r\n(\d+?)");
foreach (Match match in lines)
int color = Int32.Parse(match.Groups[5].Value);
Eu tenho outro regex para outros arquivos informações pousada também, mas o outro regex não é o problema. o problema é a regex que acabo adicionado para tentar corresponder uma cor (ARGB). é no final da string:
\r\n(\d+?)
Assim, tanto quanto eu entendo, o anterior poucos meios coisa regex isso: "Encontrar um CarriageReturn e nova linha, e depois 1 ou mais dígitos, mas não seja ganancioso". é mesmo?
Pode alguém por favor me ajudar com isso. muito obrigado.
Nota: A informação de cor que é guardada no arquivo de texto é um número negativo (cor ARGB):
-16744193
O conteúdo do arquivo é assim:
Control
Control Text
Control Location
Control Font Name
Control Font Size
Control Font Color
Explicação:
Label
"this is a label"
23, 77
Tahoma
14.0
-55794414
Assim, as obras de regex, ele recebe todos os outros detalhes corretamente, mas isso apenas não obter a informação de cor.
Solução
O regex é não o problema. Seu regex, bem como o dado por Wim funciona bem. Portanto, o problema tem que ser com a forma como a entrada está sendo manipulado.
Aqui estão algumas coisas que você pode tentar:
Executar este com entrada diferente, ou seja, em vez de usar este número:
-16744193
Use algo como isto em vez disso:
100
-100
Em seguida, imprimir o valor após esta linha:
int fcolor = Int32.Parse(match.Groups[7].Value);
E ver o que é.
Outra coisa de economia de tempo que você deve fazer é imprimir os valores em
match.Groups[1].Value
match.Groups[2].Value
match.Groups[3].Value
match.Groups[4].Value
match.Groups[5].Value
match.Groups[6].Value
match.Groups[7].Value
match.Groups[8].Value
e publicá-las aqui. Isto tornará mais fácil para você, assim como todos os no SO para ver qual é o problema.
Outras dicas
-
não é acompanhada por \d
. Além disso, se você fizer um jogo não-ganancioso em \d+
apenas o primeiro dígito serão capturados desde que satisfaça as expressões regulares. Mude sua regexp em (-?\d+)
para corresponder a um -
opcional no início do seu número e tantos dígitos como existem em número, até (mas não incluindo) o caractere após o número (nova linha, fim-de-corda, .. .).
Tente este regex e ver se funciona.
(. +?) \ R \ n "" ([^ ""] +) "" \ r \ n (\ d +), \ s (\ d +) \ r \ n ([\ w \ s] *) \ r \ n (\ d + \ d +) \ r \ n (-.? \ d +)
Seu regex parecia estar olhando para o "após o valor tamanho da fonte.
Além disso, sua cor ARGB estará em jogo do grupo 7, não 5.
Eu definir um ponto de interrupção na linha com o erro e ver o que match.Groups[5].Value
realmente é.
Eu estou apostando que ele não pode ser convertido para um int.
imprimir os valores partida como sugerido em outros lugares seria uma ajuda, bem como a redução do regexp para tornar mais fácil para isolar o problema.
Mas posso sugerir mais uma coisa. Aqui é a última parte da expressão regular a partir do tamanho jogo fonte:
..."(\d+\.\d+)\r\n(-?\d+)"
O que é suposto para o jogo contra
...
14.0
-55794414
Uma vez que você tem o jogo para a nova linha imediatamente após a partida para os dígitos de tamanho de fonte, o jogo irá falhar se você tem um espaço após 14,0. Tente com
..."(\d+\.\d+)\s*\r\n(-?\d+)"
que deve funcionar com e sem espaços à direita. (Dependendo do seu motor regexp, apenas "\s*"
pode ser melhor do que "\s*\r\n"
.)
Há realmente um monte de outras coisas que poderia dar errado. É geralmente mais fácil de dividir as cordas e trabalhar com regexps menores.
Eu suponho que você já sabe a citação?
Algumas pessoas, quando confrontado com um problema, pensar "Eu sei, eu vou usar expressões regulares." Agora eles têm dois problemas.
Você tem apenas 4 grupos em suas expressões regulares, mas você está tentando grupos de acesso de 5 a 8 que serão strings vazias, e uma string vazia não pode ser analisado como um número inteiro por Int32.Parse.
Você pode usar esse regex:
@"(.+)\r\n""([^""]+)""\r\n(\d+),\s(\d+)\r\n([\w\s]*)\r\n(\d+\.\d+)\r\n(-?\d+)"
Um exemplo de uso a partir do qual pode-se ver que ele funciona:
string value = @"Label
""this is a label""
23, 77
Tahoma
14.0
-55794414
Label
""this is a label""
23, 77
Tahoma
14.0
-55794415";
MatchCollection lines = Regex.Matches(
value,
@"(.+)\r\n""([^""]+)""\r\n(\d+),\s(\d+)\r\n([\w\s]*)\r\n(\d+\.\d+)\r\n(-?\d+)");
var colors = new List<int>();
foreach (Match match in lines)
{
colors.Add(Int32.Parse(match.Groups[7].Value));
}
CollectionAssert.AreEquivalent(new[] { -55794414, -55794415}, colors);
Neste exemplo temos 2 etiquetas com cores diferentes, como pode ser visto a regex coincide com as cores.
Os grupos de regex:
- 0 : Controle
- 1 : Texto
- 2 : X
-
3 : Y - 4 : Font
- 6 : Tamanho
- 7 : Cor