Centrum skryptów - Systemy operacyjne

Jak usunąć wszystkie niealfabetyczne znaki z ciągu?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Cześć Skrypciarze!

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Jak usunąć wszystkie niealfabetyczne znaki z ciągu?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Jak usunąć wszystkie niealfabetyczne znaki z ciągu?

-- CD

Cześć Skrypciarze! Odpowiedź

Cześć, CD. Wiecie o tym, że Skrypciarze nie faworyzują nikogo, prawda? Że traktujemy wszystkich naszych czytelników i każde otrzymane pytanie jednakowo. (No dobra, praktycznie oznacza to ni mniej, ni więcej, tylko tyle, że w większości przypadków ignorujemy naszych czytelników oraz otrzymane pytania. Ale przynajmniej wszystkich traktujemy jednakowo!)

Tym razem jednak jesteśmy zmuszeni zrobić wyjątek, CD, to jest naprawdę świetne pytanie, jedno z najlepszych, jakie kiedykolwiek otrzymaliśmy. Bardzo za nie dziękujemy!

Tak czy siak, najlepszym sposobem na usunięcie – zaraz, zaraz. Czy to jest świetne pytanie, ponieważ dotyczy spraw bliskich osobom piszącym skrypty administracyjne? Cóż, prawdę mówiąc, nie wiemy dokładnie, ilu ludzi może chcieć usunąć wszystkie niealfabetyczne znaki z ciągu, chociaż już wcześniej otrzymywaliśmy tego typu pytania. Czy jest to zatem świetne pytanie ponieważ dostarcza Skrypciarzom okazji do wyjaśnienia ważnej, acz często niezrozumiałej kwestii z zakresu roli skryptów w administracji systemu? Cóż, może. Ale to nie jest powód dla którego uznaliśmy to pytanie za takie świetne. Uznaliśmy je za takowe, ponieważ wiedzieliśmy, że możemy na nie odpowiedzieć w ciągu kilku minut, wykorzystując kilka wierszy kodu. To z kolei oznacza, że możemy szybko zamknąć dzisiejszą rubrykę i zająć się czymś innym, co nas naprawdę obchodzi: dziś jest mecz międzyszkolny, w którym bierze udział mój syn.

Zaczyna się on już niebawem i dlatego tak mi zależy na czasie, więc lepiej już zacznę odpowiadać na to pytanie (świetne, jak już mówiłem):

Set objRegEx = CreateObject("VBScript.RegExp")



objRegEx.Global = True   

objRegEx.Pattern = "[^A-Za-z]"



strSearchString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz!@#$%&*(_+"



strSearchString = objRegEx.Replace(strSearchString, "")



Wscript.Echo strSearchString

Widzicie? Mówiłem przecież, że pójdzie łatwo. I szybko.

Pomimo, iż istnieją inne sposoby na wykonanie tego zadania, naszym zdaniem najprostszym podejściem jest zastosowanie wyrażenia regularnego. Dlatego też naszym pierwszym krokiem w tym skrypcie jest zastosowanie poniższego wiersza kodu, który tworzy wystąpienie obiektu wyrażenia regularnego języka VBScript (VBScript.RegExp):

Set objRegEx = CreateObject("VBScript.RegExp")

Kiedy już mamy utworzony obiekt wyrażenia regularnego, ustawiamy dla niego dwie ważne właściwości. Po pierwsze, ustawiamy wartość właściwości Global na True; dzięki temu po uruchomieniu metody Replace wyrażenie regularne przeszuka całą wartość ciągu. Co by było, gdybyśmy nie ustawili właściwości Global na True? W takim przypadku nasze wyrażenie regularne znajdzie pierwsze wystąpienie tekstu docelowego (czyli pierwszy znak niealfabetyczny), a potem się zatrzyma. Oczywiście czasami wystarczy wiedzieć, czy w ciągu znajduje się przynajmniej jeden niealfabetyczny znak. Ale tym razem to nie wystarczy.

Następnie musimy określić właściwość Pattern wyrażenia regularnego, czyli tekst, który mamy zamiar wyszukać. Załatwiamy to za pomocą poniższego wiersza kodu:

objRegEx.Pattern = "[^A-Za-z]"

Kluczem do pracy z wyrażeniami regularnymi jest to, że nie wolno się przestraszyć tej zagadkowej składni. Zdecydowanie za często zdarza się, że patrząc na twór typu [^A-Za-z] ludzie myślą: „Nie wiem, dla kogo jest to przeznaczone, ale na pewno nie jest to przeznaczone dla mnie”. Jak się okazuje, jest to jednak całkiem prosta i bezpośrednia instrukcja. Jeżeli chodzi o wyrażenia regularne, możemy wyszukać zakres znaków, umieszczając je po prostu w nawiasach kwadratowych. Chcecie wyszukać wszystkie znaki z przedziału od A do Z (wersaliki) włącznie? Zastosujcie składnię: [A-Z]. A co z wszystkimi minuskułami z przedziału od a do z włącznie? Żaden problem: [a-z]. A gdybyśmy tak chcieli wyszukać wersaliki lub minuskuły? Jednym ze sposobów, by to osiągnąć, jest uwzględnienie obydwu przedziałów znaków w pojedynczych nawiasach kwadratowych: [A-Za-z].

Jak mówiłem, prosta i bezpośrednia składnia.

No dobra, a co z małym znakiem karetki (^)? Cóż, za każdym razem, gdy znak ten pojawia się przy przedziale znaków, znaczy tyle, co słowo „nie”. Co oznacza składnia [^A-Za-z]? Oznacza ona, że wyszukiwane będą znaki nienależące ani do przedziału A-Z, ani a-z. Innymi słowy, wyszukane zostaną wszelkie znaki niealfabetyczne.

Tak się fajnie składa, że to jest właśnie to, czego szukamy.

Możecie wierzyć lub nie, ale od tego momentu zadanie jest o wiele prostsze. Na początek przypisujemy wartość do zmiennej o nazwie strSearchString; zauważmy, że wartość ta zawiera wiele znaków niealfabetycznych.

strSearchString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz!@#$%&*(_+"

Następnie wywołujemy metodę Replace i przekazujemy jej dwa parametry: wartość, którą chcemy wyszukać (strSearchString) oraz tekst do zastąpienia. W tym przypadku oczywiście chcemy zastąpić niealfabetyczne znaki niczym; dlatego też stosujemy pusty ciąg („”) jako tekst zastąpienia:

strSearchString = objRegEx.Replace(strSearchString, "")

Ten wiersz kodu powinien usunąć wszystkie znaki niealfabetyczne ze zmiennej strSearchString. (Czyli powinien zlokalizować każdy z tych znaków i zastąpić go po prostu niczym.) A zatem, czy ten wiersz kodu rzeczywiście usuwa wszystkie znaki niealfabetyczne, znajdujące się w zmiennej strSearchString? Zobaczmy co się dzieje, kiedy wywołujemy echo wartości zmiennej strSearchString:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Kto by się spodziewał?!

Na wypadek, gdyby ktoś się zastanawiał: tak, można wykorzystać to samo podejście w celu zastąpienia wszystkich niealfabetycznych znaków w pliku tekstowym; dorzucamy przykładowy skrypt, który właśnie to robi. Zauważcie, że w przypadku tego skryptu dodałem coś do Pattern: \n\r. Dzięki temu skrypt będzie wiedział, ze chcemy wyłączyć znak nowego wiersza (\n) oraz znak powrotu karetki (\r) z zakresu wyszukiwania. To z kolei oznacza, że nasz skrypt nie usunie z pliku tekstowego żadnych znaków podziału wiersza. Jeżeli nie zależy nam na zachowaniu podziału wierszy, po prostu usuwamy \n\r z Pattern.

Nie zagłębiając się w zbędne szczegóły, przedstawiamy skrypt:

Const ForReading = 1

Const ForWriting = 2



Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForReading)



strSearchString = objFile.ReadAll

objFile.Close



Set objRegEx = CreateObject("VBScript.RegExp")



objRegEx.Global = True   

objRegEx.Pattern = "[^A-Za-z\n\r]"



strSearchString = objRegEx.Replace(strSearchString, "")



Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt", ForWriting)

objFile.WriteLine strSearchString

     

objFile.Close

Taki mały bonusowy skrypt dla każdego. Chyba nie muszę dodawać, że przed każdym meczem, w którym gra mój syn, jestem bardzo podekscytowany. To się zazwyczaj szybko zmienia.

Kiedy już jestem na meczu zaczynam się denerwować w inny sposób. Ale o tym już innym razem.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne