Analisi delle stringhe, estrarre numeri e lettere
-
09-09-2019 - |
Domanda
Qual è il modo più semplice per analizzare una stringa ed estrarre un numero e una lettera? Ho una stringa che può essere nel seguente formato (numero | lettera o lettera | numero), cioè "10a", "b5", "c10", "1g", ecc.
Devo estrarre le 2 parti, cioè "10a" -> "10" e "A".
Aggiornare: Grazie a tutti per tutte le risposte eccellenti
Soluzione
Il modo più semplice è probabilmente usare espressioni regolari.
((?<number>\d+)(?<letter>[a-zA-Z])|(?<letter>[a-zA-Z])(?<number>\d+))
Puoi quindi abbinarla alla tua stringa ed estrarre il valore dai gruppi.
Match match = regex.Match("10A");
string letter = match.Groups["letter"].Value;
int number = int.Parse(match.Groups["number"].Value);
Altri suggerimenti
Il più semplice e veloce è utilizzare semplici operazioni di stringa. Utilizzare il IsDigit
Metodo per verificare dove si trova la lettera e analizza il resto della stringa a un numero:
char letter = str[0];
int index = 1;
if (Char.IsDigit(letter)) {
letter = str[str.Length - 1];
index = 0;
}
int number = int.Parse(str.Substring(index, str.Length - 1));
char letter = str.Single(c => char.IsLetter(c));
int num = int.Parse(new string(str.Where(c => char.IsDigit(c)).ToArray()));
Questa soluzione non è terribilmente severa (consentirebbe cose come "5a2" e restituirebbe 'A' e 52) ma può andare bene per i tuoi scopi.
Solo per essere diversi:
string number = input.Trim("ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray());
string letter = input.Trim("0123456789".ToCharArray());
Ecco come mi avvicinerei a questo. Puoi passare attraverso questo e mettere GC1 ["Letter"], GC1 ["Numero"], GC2 ["Letter"] e GC2 ["Numero"] nella finestra dell'orologio per vedere che ha funzionato (passo oltre l'ultimo riga di codice qui, ovviamente).
L'epxression normale prenderà uno schema che richiede una o più lettere e numero in ciascun caso.
Regex pattern = new Regex("^(?<letter>[a-zA-Z]+)(?<number>[0-9]+)|(?<number>[0-9]+)(?<letter>[a-zA-Z]+)$");
string s1 = "12A";
string s2 = "B45";
Match m1 = pattern.Match(s1);
Match m2 = pattern.Match(s2);
GroupCollection gc1 = m1.Groups;
GroupCollection gc2 = m2.Groups;
Usando Sprache e alcuni Linq Kung-Fu:
var tagParser =
from a in Parse.Number.Or(Parse.Letter.Once().Text())
from b in Parse.Letter.Once().Text().Or(Parse.Number)
select char.IsDigit(a[0]) ?
new{Number=a, Letter=b} : new{Number=b, Letter=a};
var tag1 = tagParser.Parse("10A");
var tag2 = tagParser.Parse("A10");
tag1.Letter; // should be A
tag1.Number; // should be 10
tag2.Letter; // should be A
tag2.Number; // should be 10
/* Output:
A
10
A
10
*/