Czy istnieje funkcja Python, która przycina białe znaki (spacje i tabulatory) z ciągu?
Przykład: \t example string\t
→example string
string.whitespace
.
Czy istnieje funkcja Python, która przycina białe znaki (spacje i tabulatory) z ciągu?
Przykład: \t example string\t
→example string
string.whitespace
.
Odpowiedzi:
Biała spacja po obu stronach:
s = " \t a string example\t "
s = s.strip()
Biała spacja po prawej stronie:
s = s.rstrip()
Biała spacja po lewej stronie:
s = s.lstrip()
Jak wskazuje thedz , możesz podać argument, aby usunąć dowolne znaki z dowolnej z następujących funkcji:
s = s.strip(' \t\n\r')
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
:
import re
print re.sub('[\s+]', '', s)
To powinno wydrukować:
astringexample
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, a replace(" ", "")
nie będą.
Dla wiodących i końcowych białych znaków:
s = ' foo \t '
print s.strip() # prints "foo"
W przeciwnym razie działa wyrażenie regularne:
import re
pat = re.compile(r'\s+')
s = ' \t foo \t bar \t '
print pat.sub('', s) # prints "foobar"
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
wypowiedzi
Możesz także użyć bardzo prostej i podstawowej funkcji: str.replace () , działa z białymi spacjami i kartami:
>>> whitespaces = " abcd ef gh ijkl "
>>> tabs = " abcde fgh ijkl"
>>> print whitespaces.replace(" ", "")
abcdefghijkl
>>> print tabs.replace(" ", "")
abcdefghijkl
Proste i łatwe.
#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 ']
Nikt jeszcze nie opublikował tych wyrażeń regularnych.
Pasujący:
>>> import re
>>> p=re.compile('\\s*(.*\\S)?\\s*')
>>> m=p.match(' \t blah ')
>>> m.group(1)
'blah'
>>> m=p.match(' \tbl ah \t ')
>>> m.group(1)
'bl ah'
>>> m=p.match(' \t ')
>>> print m.group(1)
None
Wyszukiwanie (musisz inaczej traktować wielkość liter „jedyne spacje”):
>>> p1=re.compile('\\S.*\\S')
>>> m=p1.search(' \tblah \t ')
>>> m.group()
'blah'
>>> m=p1.search(' \tbl ah \t ')
>>> m.group()
'bl ah'
>>> m=p1.search(' \t ')
>>> m.group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
Jeśli używasz re.sub
, możesz usunąć wewnętrzne białe znaki, co może być niepożądane.
(re.sub ('+', '', (my_str.replace ('\ n', '')))). strip ()
Spowoduje to usunięcie wszystkich niechcianych spacji i znaków nowej linii. Mam nadzieję, że to pomoże
import re
my_str = ' a b \n c '
formatted_str = (re.sub(' +', ' ',(my_str.replace('\n',' ')))).strip()
Spowoduje to:
„a b \ nc” zostanie zmienione na „ab c”
something = "\t please_ \t remove_ all_ \n\n\n\nwhitespaces\n\t "
something = "".join(something.split())
wynik:
please_remove_all_whitespaces
something = "\t please \t remove all extra \n\n\n\nwhitespaces\n\t "
something = " ".join(something.split())
wynik:
usuń wszystkie dodatkowe białe znaki
Jeśli używasz Python 3: w instrukcji print zakończ sep = "". To oddzieli wszystkie przestrzenie.
PRZYKŁAD:
txt="potatoes"
print("I love ",txt,"",sep="")
Spowoduje to wydrukowanie: Kocham ziemniaki.
Zamiast: Kocham ziemniaki.
W twoim przypadku, ponieważ chciałbyś przejechać \ t, wykonaj sep = "\ t"
Po przyjrzeniu się kilku rozwiązaniom o różnym stopniu zrozumienia, zastanawiałem się, co zrobić, jeśli ciąg zostanie oddzielony przecinkiem ...
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ć.
[\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, )_(, jim.somedude@blahblah.com, ,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:
Here is 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, )_(, jim.somedude@blahblah.com, ,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, jim.somedude@blahblah.com, 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()'?
Here is the text, formatted as is:
"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, )_(, jim.somedude@blahblah.com, ,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"
Here is 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, )_(, jim.somedude@blahblah.com, ,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ń.
spróbuj przetłumaczyć
>>> import string
>>> print '\t\r\n hello \r\n world \t\r\n'
hello
world
>>> tr = string.maketrans(string.whitespace, ' '*len(string.whitespace))
>>> '\t\r\n hello \r\n world \t\r\n'.translate(tr)
' hello world '
>>> '\t\r\n hello \r\n world \t\r\n'.translate(tr).replace(' ', '')
'helloworld'
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.
Ogólnie używam następującej metody:
>>> 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.
do usuwania białych znaków ze środka łańcucha
$p = "ATGCGAC ACGATCGACC";
$p =~ s/\s//g;
print $p;
wynik:
ATGCGACACGATCGACC
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:
>>> s = " \n\t \n some \n text \n "
>>> re.sub("^\s+|\s+$", "", s)
>>> "some \n text"
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.