Znaki python uważa, że białe znaki są przechowywane w string.whitespace.
John Fouhy
2
Przez „funkcję pasków” masz na myśli metodę pasków? „Wygląda na to, że nie działa w przypadku moich danych wejściowych” Podaj kod, dane wejściowe i wyjściowe.
Ostatni przykład jest dokładnie taki jak przy użyciu str.replace(" ",""). Nie musisz używać re, chyba że masz więcej niż jedno miejsce, wtedy twój przykład nie działa. []jest przeznaczony do oznaczania pojedynczych znaków, nie jest to konieczne, jeśli używasz tylko \s. Użyj jednego \s+lub [\s]+(zbędne), ale [\s+]nie wykonać zadanie, zwłaszcza jeśli chcesz zastąpić wielokrotne spacje z jednego spośród takich jak toczenie "this example" się "this example".
Jorge E. Cardona,
3
@ JorgeE.Cardona - Jedną z rzeczy, o których się nieco mylisz - \sbędą zawierać karty, a replace(" ", "")nie będą.
Ale to, niestety, usuwa również przestrzeń wewnętrzną, podczas gdy przykład w pierwotnym pytaniu pozostawia wewnętrzne przestrzenie nietknięte.
Brandon Rhodes,
12
#how to trim a multi line string or a file
s=""" line one
\tline two\t
line three """#line1 starts with a space, #2 starts and ends with a tab, #3 ends with a space.
s1=s.splitlines()print s1
[' line one','\tline two\t','line three ']print[i.strip()for i in s1]['line one','line two','line three']#more details:#we could also have used a forloop from the begining:for line in s.splitlines():
line=line.strip()
process(line)#we could also be reading a file line by line.. e.g. my_file=open(filename), or with open(filename) as myfile:for line in my_file:
line=line.strip()
process(line)#moot point: note splitlines() removed the newline characters, we can keep them by passing True:#although split() will then remove them anyway..
s2=s.splitlines(True)print s2
[' line one\n','\tline two\t\n','line three ']
Po przyjrzeniu się kilku rozwiązaniom o różnym stopniu zrozumienia, zastanawiałem się, co zrobić, jeśli ciąg zostanie oddzielony przecinkiem ...
problem
Próbując przetworzyć plik CSV z danymi kontaktowymi, potrzebowałem rozwiązania tego problemu: przyciąć zbędne białe znaki i niektóre śmieci, ale zachować końcowe przecinki i wewnętrzne białe znaki. Pracując z polem zawierającym notatki o kontaktach, chciałem usunąć śmieci, pozostawiając dobre rzeczy. Przycinając wszystkie znaki interpunkcyjne i plewy, nie chciałem stracić spacji między złożonymi tokenami, ponieważ nie chciałem później odbudowywać.
Wyrażenia regularne i wzorce: [\s_]+?\W+
Wzorzec szuka pojedynczych wystąpień dowolnego znaku spacji i znaku podkreślenia („_”) od 1 do nieograniczonej liczby leniwie (możliwie jak najmniej znaków), przy [\s_]+?czym poprzedzają one znaki niebędące słowami występujące od 1 do nieograniczonej liczby znaków czas z tym: \W+(jest równoważny [^a-zA-Z0-9_]). W szczególności znajduje to fragmenty białych znaków: znaki puste (\ 0), tabulatory (\ t), znaki nowej linii (\ n), feed-forward (\ f), powrót karetki (\ r).
Zaletę tego widzę podwójnie:
że nie usuwa białych znaków między pełnymi słowami / tokenami, które możesz chcieć trzymać razem;
Wbudowana w Pythona metoda ciągu strip()nie obsługuje ciągu, tylko lewy i prawy koniec, a domyślnym argumentem są znaki puste (patrz poniższy przykład: kilka znaków nowej linii jest w tekście i strip()nie usuwa ich wszystkich, podczas gdy wzorzec wyrażenia regularnego robi) .text.strip(' \n\t\r')
To wykracza poza pytanie PO, ale myślę, że istnieje wiele przypadków, w których mogliśmy mieć dziwne, patologiczne wystąpienia w danych tekstowych, tak jak ja (niektóre, w jaki sposób znaki specjalne kończyły się w niektórych tekstach). Ponadto w ciągach podobnych do list nie chcemy eliminować separatora, chyba że separator oddzieli dwa białe znaki lub niektóre znaki niebędące znakami, takie jak „-,” lub „-, ,,,”.
NB: Nie mówię o ograniczniku samego CSV. Tylko przypadki w CSV, w których dane są podobne do listy, tzn. Są łańcuchem znaków podciągów cs.
Pełne ujawnienie: manipuluję tekstem przez około miesiąc, a regex tylko przez ostatnie dwa tygodnie, więc jestem pewien, że brakuje mi pewnych niuansów. To powiedziawszy, w przypadku mniejszych kolekcji ciągów (moje są w ramce danych 12 000 wierszy i 40 nieparzystych kolumn), jako ostatni krok po przejściu do usunięcia obcych znaków, działa to wyjątkowo dobrze, szczególnie jeśli wprowadzisz dodatkowe białe znaki w miejscu, w którym chcesz oddzielić tekst, do którego dołącza się znak niebędący słowem, ale nie chcesz dodawać spacji tam, gdzie wcześniej nie było.
Przykład:
import re
text ="\"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12, 2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , , dd invites,subscribed, , , , \r, , \0, ff dd \n invites, subscribed, , , , , alumni spring 2012 deck: https: www.dropbox.com s, \n i69rpofhfsp9t7c practice 20ignition - 20june \t\n .2134.pdf 2109 \n\n\n\nklkjsdf\""print(f"Here is the text as formatted:\n{text}\n")print()print("Trimming both the whitespaces and the non-word characters that follow them.")print()
trim_ws_punctn = re.compile(r'[\s_]+?\W+')
clean_text = trim_ws_punctn.sub(' ', text)print(clean_text)print()print("what about 'strip()'?")print(f"Here is the text, formatted as is:\n{text}\n")
clean_text = text.strip(' \n\t\r')# strip out whitespace?print()print(f"Here is the text, formatted as is:\n{clean_text}\n")print()print("Are 'text' and 'clean_text' unchanged?")print(clean_text == text)
To daje:
Hereis the text as formatted:"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12, 2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , , dd invites,subscribed, ,, , , ff dd
invites, subscribed, , , , , alumni spring 2012 deck: https: www.dropbox.com s,
i69rpofhfsp9t7c practice 20ignition - 20june
.2134.pdf 2109
klkjsdf"
using regex to trim both the whitespaces and the non-word characters that follow them."portfolio, derp, hello-world, hello-, world, founders, mentors, ffib, biff, 1, 12.18.02, 12, 2013, 9874890288, ff, series a, exit, general mailing, fr, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, [email protected], dd invites,subscribed,, master, dd invites,subscribed, ff dd invites, subscribed, alumni spring 2012 deck: https: www.dropbox.com s, i69rpofhfsp9t7c practice 20ignition 20june 2134.pdf 2109 klkjsdf"Very nice.What about 'strip()'?Hereis the text, formatted asis:"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12, 2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , , dd invites,subscribed, ,, , , ff dd
invites, subscribed, , , , , alumni spring 2012 deck: https: www.dropbox.com s,
i69rpofhfsp9t7c practice 20ignition - 20june
.2134.pdf 2109
klkjsdf"Hereis the text, after stipping with'strip':"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12, 2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , , dd invites,subscribed, ,, , , ff dd
invites, subscribed, , , , , alumni spring 2012 deck: https: www.dropbox.com s,
i69rpofhfsp9t7c practice 20ignition - 20june
.2134.pdf 2109
klkjsdf"Are'text'and'clean_text' unchanged?'True'
Tak więc pasek usuwa po jednym spacji. Więc w przypadku PO strip()jest w porządku. ale jeśli sytuacja stanie się bardziej złożona, wyrażenie regularne i podobny wzór mogą mieć pewną wartość dla bardziej ogólnych ustawień.
Jeśli chcesz przyciąć białe znaki tylko na początku i na końcu łańcucha, możesz zrobić coś takiego:
some_string =" Hello, world!\n "
new_string = some_string.strip()# new_string is now "Hello, world!"
Działa to bardzo podobnie do metody Qt QString :: trimmed (), ponieważ usuwa początkowe i końcowe białe spacje, pozostawiając wewnętrzne białe spacje w spokoju.
Ale jeśli chcesz czegoś takiego jak metoda QString :: uproszczona () Qt, która nie tylko usuwa wiodące i końcowe białe spacje, ale także „wyrównuje” wszystkie kolejne wewnętrzne białe spacje do jednego znaku spacji, możesz użyć kombinacji .split()i " ".join, w ten sposób:
some_string ="\t Hello, \n\t world!\n "
new_string =" ".join(some_string.split())# new_string is now "Hello, world!"
W tym ostatnim przykładzie każda sekwencja wewnętrznych białych znaków została zastąpiona pojedynczą spacją, wciąż przycinając białe znaki na początku i na końcu łańcucha.
>>> myStr ="Hi\n Stack Over \r flow!">>> charList =[u"\u005Cn",u"\u005Cr",u"\u005Ct"]>>>import re
>>>for i in charList:
myStr = re.sub(i, r"", myStr)>>> myStr
'Hi Stack Over flow'
Uwaga: służy tylko do usuwania „\ n”, „\ r” i „\ t”. Nie usuwa dodatkowych spacji.
Po co używać wyrażenia regularnego, kiedy s.strip()dokładnie to robi?
Ned Batchelder
1
s.strip()obsługuje tylko początkowe białe znaki, ale nie „odkrywa” białych znaków po usunięciu innych niechcianych znaków. Pamiętaj, że spowoduje to usunięcie nawet spacji po ostatnim prowadzeniu\n
Rafe
Ktoś zlekceważył tę odpowiedź, ale nie wyjaśnił, dlaczego jest ona wadliwa. Wstydź się (@NedBatchelder, jeśli głos był negatywny, proszę cofnąć, ponieważ wyjaśniłem twoje pytanie i nie wspomniałeś o niczym, co faktycznie zostało złamane z moją odpowiedzią)
Rafe
10
Rafe, możesz chcieć dwukrotnie sprawdzić: s.strip()daje dokładnie taki sam wynik jak wyrażenie regularne.
Ned Batchelder,
3
@Rafe, mylisz to z wykończeniem. Strip wykonuje wymagane operacje.
string.whitespace
.Odpowiedzi:
Biała spacja po obu stronach:
Biała spacja po prawej stronie:
Biała spacja po lewej stronie:
Jak wskazuje thedz , możesz podać argument, aby usunąć dowolne znaki z dowolnej z następujących funkcji:
Będzie to rozebrać każdą przestrzeń,
\t
,\n
, lub\r
znaki z lewej strony, po prawej stronie, albo po obu stronach łańcucha.Powyższe przykłady usuwają tylko łańcuchy z lewej i prawej strony łańcuchów. Jeśli chcesz również usunąć znaki ze środka ciągu, spróbuj
re.sub
:To powinno wydrukować:
źródło
str.replace(" ","")
. Nie musisz używaćre
, chyba że masz więcej niż jedno miejsce, wtedy twój przykład nie działa.[]
jest przeznaczony do oznaczania pojedynczych znaków, nie jest to konieczne, jeśli używasz tylko\s
. Użyj jednego\s+
lub[\s]+
(zbędne), ale[\s+]
nie wykonać zadanie, zwłaszcza jeśli chcesz zastąpić wielokrotne spacje z jednego spośród takich jak toczenie"this example"
się"this example"
.\s
będą zawierać karty, areplace(" ", "")
nie będą.trim
Metoda Python nazywa sięstrip
:źródło
Dla wiodących i końcowych białych znaków:
W przeciwnym razie działa wyrażenie regularne:
źródło
pat = re.compile(r'\s+')
sub(" ", s)
nie""
później będzie łączyć słowa i nie będziesz już w stanie wykorzystać.split(" ")
do tokenize.print
wypowiedziMożesz także użyć bardzo prostej i podstawowej funkcji: str.replace () , działa z białymi spacjami i kartami:
Proste i łatwe.
źródło
źródło
Nikt jeszcze nie opublikował tych wyrażeń regularnych.
Pasujący:
Wyszukiwanie (musisz inaczej traktować wielkość liter „jedyne spacje”):
Jeśli używasz
re.sub
, możesz usunąć wewnętrzne białe znaki, co może być niepożądane.źródło
Białe znaki obejmują spację, tabulatory i CRLF . Zatem elegancką i jednowarstwową funkcją struny, której możemy użyć jest tłumaczenie .
' hello apple'.translate(None, ' \n\t\r')
LUB jeśli chcesz być dokładny
źródło
Spowoduje to usunięcie wszystkich niechcianych spacji i znaków nowej linii. Mam nadzieję, że to pomoże
Spowoduje to:
„a b \ nc” zostanie zmienione na „ab c”
źródło
wynik:
Dodanie komentarza Le Droida do odpowiedzi. Aby oddzielić spacją:
wynik:
źródło
Jeśli używasz Python 3: w instrukcji print zakończ sep = "". To oddzieli wszystkie przestrzenie.
PRZYKŁAD:
Spowoduje to wydrukowanie: Kocham ziemniaki.
Zamiast: Kocham ziemniaki.
W twoim przypadku, ponieważ chciałbyś przejechać \ t, wykonaj sep = "\ t"
źródło
Po przyjrzeniu się kilku rozwiązaniom o różnym stopniu zrozumienia, zastanawiałem się, co zrobić, jeśli ciąg zostanie oddzielony przecinkiem ...
problem
Próbując przetworzyć plik CSV z danymi kontaktowymi, potrzebowałem rozwiązania tego problemu: przyciąć zbędne białe znaki i niektóre śmieci, ale zachować końcowe przecinki i wewnętrzne białe znaki. Pracując z polem zawierającym notatki o kontaktach, chciałem usunąć śmieci, pozostawiając dobre rzeczy. Przycinając wszystkie znaki interpunkcyjne i plewy, nie chciałem stracić spacji między złożonymi tokenami, ponieważ nie chciałem później odbudowywać.
Wyrażenia regularne i wzorce:
[\s_]+?\W+
Wzorzec szuka pojedynczych wystąpień dowolnego znaku spacji i znaku podkreślenia („_”) od 1 do nieograniczonej liczby leniwie (możliwie jak najmniej znaków), przy
[\s_]+?
czym poprzedzają one znaki niebędące słowami występujące od 1 do nieograniczonej liczby znaków czas z tym:\W+
(jest równoważny[^a-zA-Z0-9_]
). W szczególności znajduje to fragmenty białych znaków: znaki puste (\ 0), tabulatory (\ t), znaki nowej linii (\ n), feed-forward (\ f), powrót karetki (\ r).Zaletę tego widzę podwójnie:
że nie usuwa białych znaków między pełnymi słowami / tokenami, które możesz chcieć trzymać razem;
Wbudowana w Pythona metoda ciągu
strip()
nie obsługuje ciągu, tylko lewy i prawy koniec, a domyślnym argumentem są znaki puste (patrz poniższy przykład: kilka znaków nowej linii jest w tekście istrip()
nie usuwa ich wszystkich, podczas gdy wzorzec wyrażenia regularnego robi) .text.strip(' \n\t\r')
To wykracza poza pytanie PO, ale myślę, że istnieje wiele przypadków, w których mogliśmy mieć dziwne, patologiczne wystąpienia w danych tekstowych, tak jak ja (niektóre, w jaki sposób znaki specjalne kończyły się w niektórych tekstach). Ponadto w ciągach podobnych do list nie chcemy eliminować separatora, chyba że separator oddzieli dwa białe znaki lub niektóre znaki niebędące znakami, takie jak „-,” lub „-, ,,,”.
NB: Nie mówię o ograniczniku samego CSV. Tylko przypadki w CSV, w których dane są podobne do listy, tzn. Są łańcuchem znaków podciągów cs.
Pełne ujawnienie: manipuluję tekstem przez około miesiąc, a regex tylko przez ostatnie dwa tygodnie, więc jestem pewien, że brakuje mi pewnych niuansów. To powiedziawszy, w przypadku mniejszych kolekcji ciągów (moje są w ramce danych 12 000 wierszy i 40 nieparzystych kolumn), jako ostatni krok po przejściu do usunięcia obcych znaków, działa to wyjątkowo dobrze, szczególnie jeśli wprowadzisz dodatkowe białe znaki w miejscu, w którym chcesz oddzielić tekst, do którego dołącza się znak niebędący słowem, ale nie chcesz dodawać spacji tam, gdzie wcześniej nie było.
Przykład:
To daje:
Tak więc pasek usuwa po jednym spacji. Więc w przypadku PO
strip()
jest w porządku. ale jeśli sytuacja stanie się bardziej złożona, wyrażenie regularne i podobny wzór mogą mieć pewną wartość dla bardziej ogólnych ustawień.zobacz to w akcji
źródło
spróbuj przetłumaczyć
źródło
Jeśli chcesz przyciąć białe znaki tylko na początku i na końcu łańcucha, możesz zrobić coś takiego:
Działa to bardzo podobnie do metody Qt QString :: trimmed (), ponieważ usuwa początkowe i końcowe białe spacje, pozostawiając wewnętrzne białe spacje w spokoju.
Ale jeśli chcesz czegoś takiego jak metoda QString :: uproszczona () Qt, która nie tylko usuwa wiodące i końcowe białe spacje, ale także „wyrównuje” wszystkie kolejne wewnętrzne białe spacje do jednego znaku spacji, możesz użyć kombinacji
.split()
i" ".join
, w ten sposób:W tym ostatnim przykładzie każda sekwencja wewnętrznych białych znaków została zastąpiona pojedynczą spacją, wciąż przycinając białe znaki na początku i na końcu łańcucha.
źródło
Ogólnie używam następującej metody:
Uwaga: służy tylko do usuwania „\ n”, „\ r” i „\ t”. Nie usuwa dodatkowych spacji.
źródło
do usuwania białych znaków ze środka łańcucha
wynik:
źródło
Spowoduje to usunięcie wszystkich białych znaków i znaków nowej linii zarówno na początku, jak i na końcu łańcucha:
źródło
s.strip()
dokładnie to robi?s.strip()
obsługuje tylko początkowe białe znaki, ale nie „odkrywa” białych znaków po usunięciu innych niechcianych znaków. Pamiętaj, że spowoduje to usunięcie nawet spacji po ostatnim prowadzeniu\n
s.strip()
daje dokładnie taki sam wynik jak wyrażenie regularne.