Dla tych z nas, których RegEx zakwestionował, czy mógłbyś napisać swój zwykły angielski wzór RegEx? Innymi słowy, „^ robi to” itp.
Metro Smurf
47
@Metro Smurf ^ nie jest operatorem. Mówi wyrażeniu regularnemu, aby znalazł wszystko, co nie pasuje, zamiast wszystkiego, co pasuje. Znak \ u #### - \ u #### mówi, które znaki pasują. \ U0000- \ u007F jest ekwiwalentem pierwszych 255 znaków w utf-8 lub Unicode, które zawsze są znakami ascii. Więc dopasowujesz każdą postać nie ascii (z powodu nie) i zastępujesz wszystko, co pasuje.
Gordon Tucker,
41
Zakres znaków do wydrukowania to 0020-007E, dla osób szukających wyrażeń regularnych zastępujących znaki niedrukowalne
Mubashar,
1
@ GordonTucker \ u0000- \ u007F jest ekwiwalentem pierwszych 127 znaków w utf-8 lub Unicode, a NIE pierwszych 225. Patrz tabela
full_prog_full
4
@full_prog_full Dlatego odpowiedziałem sobie około minutę później, poprawiając się, twierdząc, że to 127, a nie 255. :)
Gordon Tucker
125
Oto czyste rozwiązanie .NET, które nie używa wyrażeń regularnych:
Może to wyglądać nieporęcznie, ale powinno być intuicyjne. Używa kodowania ASCII .NET do konwersji łańcucha. UTF8 jest używany podczas konwersji, ponieważ może reprezentować dowolny z oryginalnych znaków. Wykorzystuje EncoderReplacementFallback do konwersji dowolnego znaku spoza ASCII na pusty ciąg znaków.
Idealny! Używam tego do czyszczenia łańcucha przed zapisaniem go w dokumencie RTF. Bardzo mile widziane. Znacznie łatwiejszy do zrozumienia niż wersja Regex.
Nathan Prather,
21
Naprawdę łatwiej to zrozumieć? Dla mnie wszystkie rzeczy, które nie są tak naprawdę istotne (awarie, konwersje do bajtów itp.) Odwracają uwagę od tego, co się naprawdę dzieje.
bzlm
21
To trochę jak powiedzenie, że śrubokręty są zbyt mylące, więc zamiast tego użyję młotka.
Brandon
8
@Brandon, w rzeczywistości ta technika nie wykonuje tej pracy lepiej niż inne techniki. Więc analogia byłaby za pomocą zwykłego śrubokręta olde zamiast fantazyjny iScrewDriver Deluxe 2000. :)
bzlm
10
Jedną z zalet jest to, że mogę łatwo zastąpić ASCII ISO 8859-1 lub innym kodowaniem :)
Nawet nie zdawałem sobie sprawy, że to możliwe, ale jest to dla mnie znacznie lepsze rozwiązanie. Dodaję ten link do komentarza do pytania, aby ułatwić innym osobom znalezienie. Dzięki!
publicstaticstringPureAscii(thisstring source,char nil =' '){var min ='\u0000';var max ='\u007F';return source.Select(c => c < min ? nil : c > max ? nil : c).ToText();}publicstaticstringToText(thisIEnumerable<char> source){var buffer =newStringBuilder();foreach(var c in source)
buffer.Append(c);return buffer.ToString();}
Dla tych, którzy go nie złapali, jest to rozwiązanie oparte na C # 4.0 LINQ. :)
7
Zamiast oddzielnej metody ToText (), co powiesz na zamianę wiersza 3 PureAscii () na: return new string (source.Select (c => c <min? Nil: c> max? Nil: c) .ToArray ()) ;
agentnega
A może ToText jako: return (new string (source)). ToArray () - w zależności od tego, co działa najlepiej. Nadal miło jest mieć ToText jako metodę rozszerzenia - styl płynny / potokowy. :-)
Bent Rasmussen
Ten kod zastępuje znaki spoza ASCII spacją. Aby je usunąć, zmień Wybierz na Gdzie:return new string( source.Where( c => c >= min && c <= max ).ToArray() );
Foozinator
@Foozinator Ten kod pozwala określić, który znak ma zostać zastąpiony znakami spoza ASCII. Domyślnie używa spacji, ale jeśli nazywa się jak .PureASCII (Char.MinValue), zastąpi wszystkie nie-ASCII „\ 0” - co nadal nie jest dokładnie ich usuwaniem, ale podobne wyniki.
Ulfius
5
nie ma potrzeby wyrażenia regularnego. po prostu użyj kodowania ...
To nie działa. To nie usuwa znaków Unicode, zastępuje je znakiem? postać.
David
1
@David ma rację. Przynajmniej dostałem, ????nacho??kiedy próbowałem: たまねこnachoなちin mono 3.4
nacho4d
1
Możesz utworzyć własną klasę kodowania, która zamiast zastępować znaki, usuwa je. Zobacz metodę
GetEncoding
4
Uważam, że następujący nieco zmieniony zakres jest przydatny do analizowania bloków komentarzy z bazy danych, co oznacza, że nie będziesz musiał walczyć z tabulatorami i znakami ucieczki, które spowodowałyby, że pole CSV się zdenerwowało.
W przypadku, gdy nikt nie zauważył innych komentarzy, znaki do wydruku to w rzeczywistości @ „[^ \ u0020- \ u007E]”. Oto link do tabeli, jeśli jesteś ciekawy: asciitable.com
scradam
3
Przybyłem tutaj, szukając rozwiązania dla rozszerzonych postaci ascii, ale nie mogłem go znaleźć. Najbliższe znalazłem rozwiązanie bzlm . Ale działa to tylko w przypadku kodu ASCII do 127 (oczywiście można zastąpić typ kodowania w jego kodzie, ale myślę, że było to trochę skomplikowane do zrozumienia. Dlatego udostępnianie tej wersji). Oto rozwiązanie, które działa dla rozszerzonych kodów ASCII, tj. Do 255, czyli ISO 8859-1
Wyszukuje i usuwa znaki inne niż ascii (większe niż 255)
Dim str1 asString="â, ??î or ôu🕧� n☁i✑💴++$-💯♓!🇪🚑🌚‼⁉4⃣od;/⏬'®;😁☕😁:☝)😁😁///😍1!@#"Dim extendedAscii AsEncoding=Encoding.GetEncoding("ISO-8859-1",NewEncoderReplacementFallback(String.empty),NewDecoderReplacementFallback())Dim extendedAsciiBytes()AsByte= extendedAscii.GetBytes(str1)Dim str2 AsString= extendedAscii.GetString(extendedAsciiBytes)
console.WriteLine(str2)'Output : â, ??î or ôu ni++$-!‼⁉4od;/';:)///1!@#$%^yz:
Jedyny, który pracował, aby usunąć TYLKO Ω z tego ciągu „Ω c ç ã”. Dziękuję Ci bardzo!
Rafael Araújo,
2
Nie jest to optymalne pod względem wydajności, ale dość proste podejście Linq:
string strippedString =newstring(
yourString.Where(c => c <=sbyte.MaxValue).ToArray());
Minusem jest to, że wszystkie „ocalałe” postacie są najpierw umieszczane w tablicy typu, char[]która jest następnie wyrzucana po tym, jak stringkonstruktor przestanie z niej korzystać.
Odpowiedzi:
źródło
Oto czyste rozwiązanie .NET, które nie używa wyrażeń regularnych:
Może to wyglądać nieporęcznie, ale powinno być intuicyjne. Używa kodowania ASCII .NET do konwersji łańcucha. UTF8 jest używany podczas konwersji, ponieważ może reprezentować dowolny z oryginalnych znaków. Wykorzystuje EncoderReplacementFallback do konwersji dowolnego znaku spoza ASCII na pusty ciąg znaków.
źródło
Wierzę, że MonsCamus miał na myśli:
źródło
Jeśli nie chcesz rozbierać, ale faktycznie konwertować akcenty łacińskie na znaki nieakcentowane, spójrz na to pytanie: Jak przetłumaczyć znaki 8-bitowe na znaki 7-bitowe? (tj. Ü do U)
źródło
Zainspirowany rozwiązaniem wyrażeń regularnych philcruz stworzyłem czyste rozwiązanie LINQ
To jest nieprzetestowany kod.
źródło
return new string( source.Where( c => c >= min && c <= max ).ToArray() );
nie ma potrzeby wyrażenia regularnego. po prostu użyj kodowania ...
źródło
????nacho??
kiedy próbowałem:たまねこnachoなち
in mono 3.4Uważam, że następujący nieco zmieniony zakres jest przydatny do analizowania bloków komentarzy z bazy danych, co oznacza, że nie będziesz musiał walczyć z tabulatorami i znakami ucieczki, które spowodowałyby, że pole CSV się zdenerwowało.
Jeśli chcesz uniknąć innych znaków specjalnych lub określonej interpunkcji, sprawdź tabelę ascii
źródło
Przybyłem tutaj, szukając rozwiązania dla rozszerzonych postaci ascii, ale nie mogłem go znaleźć. Najbliższe znalazłem rozwiązanie bzlm . Ale działa to tylko w przypadku kodu ASCII do 127 (oczywiście można zastąpić typ kodowania w jego kodzie, ale myślę, że było to trochę skomplikowane do zrozumienia. Dlatego udostępnianie tej wersji). Oto rozwiązanie, które działa dla rozszerzonych kodów ASCII, tj. Do 255, czyli ISO 8859-1
Wyszukuje i usuwa znaki inne niż ascii (większe niż 255)
Oto działające skrzypce dla kodu
Wymień kodowanie zgodnie z wymaganiami, reszta powinna pozostać taka sama.
źródło
Nie jest to optymalne pod względem wydajności, ale dość proste podejście Linq:
Minusem jest to, że wszystkie „ocalałe” postacie są najpierw umieszczane w tablicy typu,
char[]
która jest następnie wyrzucana po tym, jakstring
konstruktor przestanie z niej korzystać.źródło
Użyłem tego wyrażenia regularnego:
źródło
Używam tego wyrażenia regularnego do odfiltrowywania złych znaków w nazwie pliku.
To powinny być wszystkie znaki dozwolone w nazwach plików.
źródło