Prawdopodobnie powinieneś IsDigitraczej użyć niż IsNumber: "Ta metoda [ IsNumber] określa, czy a Charnależy do dowolnej numerycznej kategorii Unicode. Oprócz cyfr, liczby obejmują znaki, ułamki, indeksy dolne, indeksy górne, cyfry rzymskie, liczniki walut i liczby zakreślone. Ta metoda kontrastuje z IsDigitmetodą, która określa, czy a Charjest cyfrą dziesiętną ”. msdn.microsoft.com/en-us/library/yk2b3t2y.aspx
LukeH
2
@TrevorBrooks Przypuszczam, że możesz po prostu rozszerzyć warunki:input.Where(c => char.IsDigit(c) || char.IsWhiteSpace(c))
Fredrik Mörk,
6
Można to jeszcze bardziej uprościć return new string(input.Where(char.IsDigit).ToArray());. Po prostu
sprawiam,
2
Niezła odpowiedź. Warto po prostu rozważyć zmianę nazwy funkcji z „GetNumbers” na „GetDigits” ... aby jasno określić jej zamiar.
JTech
2
To także świetna metoda przedłużania.
Roberto Bonini
61
Wygląda na to, że dobrze pasuje do wyrażenia regularnego.
var s ="40,595 p.a.";var stripped =Regex.Replace(s,"[^0-9]","");
"[^0-9]"można zastąpić, @"\D"ale podoba mi się czytelność [^0-9].
Z ciekawości, jaka jest wydajność między tą odpowiedzią a odpowiedzią Fredrika Morka?
Scuba Steve
Jest to prawdopodobnie wolniejsze, ale jedynym sposobem na poznanie jest pomiar, ponieważ zależy to od tego, jak .NET implementuje wyrażenia regularne, jak jest kompilowane Lambda Expression i nie tylko.
Jonas Elfström
1
Jest to bardziej elastyczne niż użycie IsDigit (), ponieważ można dodać „.” znaków do wyrażenia regularnego, jeśli chcesz zezwolić na liczby z miejscami dziesiętnymi.
Richard Moore
10
Zrobiłem proste porównanie Regex vs. LINQ na ciągu złożonym z 100 000 połączonych identyfikatorów GUID (w wyniku czego powstał ciąg 3 600 000 znaków). Regex był konsekwentnie około pół sekundy, podczas gdy LINQ konsekwentnie znajdował się w 1/10 drugiego zakresu. Zasadniczo LINQ był średnio 5 lub więcej razy szybszy.
Chris Pratt
8
Metoda rozszerzenia będzie lepszym podejściem:
publicstaticstringGetNumbers(thisstring text){
text = text ??string.Empty;returnnewstring(text.Where(p =>char.IsDigit(p)).ToArray());}
Wolę if (text == null) return string.Empty;więcej text = text ?? string.Empty;. W ten sposób nie zmniejszamy wydajności.
Hooman,
6
Użyj dowolnego wyrażenia regularnego, które przechwytuje tylko 0-9, a resztę odrzuca. Jednak wyrażenie regularne to operacja, która za pierwszym razem będzie dużo kosztować. Lub zrób coś takiego:
var sb =newStringBuilder();var goodChars ="0123456789".ToCharArray();var input ="40,595";foreach(var c in input){if(goodChars.IndexOf(c)>=0)
sb.Append(c);}var output = sb.ToString();
Wiesz, jakie są cyfry: 0123456789, prawda? Przemierzaj łańcuch znak po znaku; jeśli znak jest cyfrą, przyklej go do końca łańcucha tymczasowego, w przeciwnym razie zignoruj. Mogą istnieć inne metody pomocnika dostępne dla ciągów C #, ale jest to podejście ogólne, które działa wszędzie.
Co muszę zrobić, aby uzyskać Regex Working i ten błąd Nazwa „Regex” nie istnieje w bieżącym kontekście
StevieB
using System.Text.RegularExpressions;
dhirschl
0
Przyjęta odpowiedź jest świetna, jednak nie bierze pod uwagę wartości NULL, przez co jest bezużyteczna w większości scenariuszy.
To skłoniło mnie do korzystania z tych metod pomocniczych. Pierwsza odpowiada na PO, podczas gdy inne mogą być przydatne dla tych, którzy chcą zrobić coś odwrotnego:
/// <summary>/// Strips out non-numeric characters in string, returning only digits/// ref.: /programming/3977497/stripping-out-non-numeric-characters-in-string/// </summary>/// <param name="input">the input string</param>/// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>/// <returns>the input string numeric part: for example, if input is "XYZ1234A5U6" it will return "123456"</returns>publicstaticstringGetNumbers(string input,bool throwExceptionIfNull =false){return(input ==null&&!throwExceptionIfNull)? input
:newstring(input.Where(c =>char.IsDigit(c)).ToArray());}/// <summary>/// Strips out numeric and special characters in string, returning only letters/// </summary>/// <param name="input">the input string</param>/// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>/// <returns>the letters contained within the input string: for example, if input is "XYZ1234A5U6~()" it will return "XYZAU"</returns>publicstaticstringGetLetters(string input,bool throwExceptionIfNull =false){return(input ==null&&!throwExceptionIfNull)? input
:newstring(input.Where(c =>char.IsLetter(c)).ToArray());}/// <summary>/// Strips out any non-numeric/non-digit character in string, returning only letters and numbers/// </summary>/// <param name="input">the input string</param>/// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>/// <returns>the letters contained within the input string: for example, if input is "XYZ1234A5U6~()" it will return "XYZ1234A5U6"</returns>publicstaticstringGetLettersAndNumbers(string input,bool throwExceptionIfNull =false){return(input ==null&&!throwExceptionIfNull)? input
:newstring(input.Where(c =>char.IsLetterOrDigit(c)).ToArray());}
Odpowiedzi:
Jest wiele sposobów, ale to powinno wystarczyć (nie wiem jednak, jak to działa z naprawdę dużymi ciągami znaków):
źródło
IsDigit
raczej użyć niżIsNumber
: "Ta metoda [IsNumber
] określa, czy aChar
należy do dowolnej numerycznej kategorii Unicode. Oprócz cyfr, liczby obejmują znaki, ułamki, indeksy dolne, indeksy górne, cyfry rzymskie, liczniki walut i liczby zakreślone. Ta metoda kontrastuje zIsDigit
metodą, która określa, czy aChar
jest cyfrą dziesiętną ”. msdn.microsoft.com/en-us/library/yk2b3t2y.aspxinput.Where(c => char.IsDigit(c) || char.IsWhiteSpace(c))
return new string(input.Where(char.IsDigit).ToArray());
. Po prostuWygląda na to, że dobrze pasuje do wyrażenia regularnego.
"[^0-9]"
można zastąpić,@"\D"
ale podoba mi się czytelność[^0-9]
.źródło
Metoda rozszerzenia będzie lepszym podejściem:
źródło
if (text == null) return string.Empty;
więcejtext = text ?? string.Empty;
. W ten sposób nie zmniejszamy wydajności.Użyj dowolnego wyrażenia regularnego, które przechwytuje tylko 0-9, a resztę odrzuca. Jednak wyrażenie regularne to operacja, która za pierwszym razem będzie dużo kosztować. Lub zrób coś takiego:
Myślę, że coś takiego nie skompilowałem ...
LINQ jest, jak powiedział Fredrik, również opcją
źródło
Inna opcja ...
źródło
źródło
Wiesz, jakie są cyfry: 0123456789, prawda? Przemierzaj łańcuch znak po znaku; jeśli znak jest cyfrą, przyklej go do końca łańcucha tymczasowego, w przeciwnym razie zignoruj. Mogą istnieć inne metody pomocnika dostępne dla ciągów C #, ale jest to podejście ogólne, które działa wszędzie.
źródło
Oto kod wykorzystujący wyrażenia regularne:
źródło
Przyjęta odpowiedź jest świetna, jednak nie bierze pod uwagę wartości NULL, przez co jest bezużyteczna w większości scenariuszy.
To skłoniło mnie do korzystania z tych metod pomocniczych. Pierwsza odpowiada na PO, podczas gdy inne mogą być przydatne dla tych, którzy chcą zrobić coś odwrotnego:
Aby uzyskać dodatkowe informacje, przeczytaj ten post na moim blogu.
źródło
źródło