Piszę program do liczenia słów MapReduce w języku python. Problem polega na tym, że w danych jest wiele znaków innych niż alfabet, znalazłem ten post Usuwanie wszystkiego oprócz znaków alfanumerycznych z łańcucha w Pythonie, który pokazuje ładne rozwiązanie za pomocą wyrażenia regularnego, ale nie jestem pewien, jak to zaimplementować
def mapfn(k, v):
print v
import re, string
pattern = re.compile('[\W_]+')
v = pattern.match(v)
print v
for w in v.split():
yield w, 1
Obawiam się, że nie jestem pewien, jak używać biblioteki, re
a nawet wyrażenia regularnego w tym celu. Nie jestem pewien, jak v
poprawnie zastosować wzorzec wyrażenia regularnego do przychodzącego ciągu (wiersza książki), aby pobrać nowy wiersz bez żadnych znaków niealfanumerycznych.
Propozycje?
v
to cała linia książki (szczególnie moby dick), idę słowo po słowie, a nie znak po znaku. Dlatego niektóre słowa mogą mieć na końcu „,”, więc „zniewaga” nie pokrywa się z „zniewagą”.Odpowiedzi:
Posługiwać się
re.sub
import re regex = re.compile('[^a-zA-Z]') #First parameter is the replacement, second parameter is your input string regex.sub('', 'ab3d*E') #Out: 'abdE'
Alternatywnie, jeśli chcesz usunąć tylko określony zestaw znaków (jako apostrof może być w porządku w twoim wejściu ...)
regex = re.compile('[,\.!?]') #etc.
źródło
^a-zA-Z
zamiast tylko^a-zA-Z
a-zA-Z \n
. Próbuję znaleźć wyrażenie regularne, które połączyłoby oba te elementy w jedno, ale używając\w
lub\W
nie zapewniając mi pożądanego zachowania. Możesz po prostu dodać,\n
jeśli tak jest.Jeśli wolisz nie używać wyrażenia regularnego, możesz spróbować
''.join([i for i in s if i.isalpha()])
źródło
Możesz użyć funkcji re.sub (), aby usunąć te znaki:
>>> import re >>> re.sub("[^a-zA-Z]+", "", "ABC12abc345def") 'ABCabcdef'
re.sub (DOPASUJ WZÓR, ZAMIEŃ ŁAŃCUCH, ŁAŃCUCH DO SZUKANIA)
"[^a-zA-Z]+"
- poszukaj dowolnej grupy znaków, które NIE są a-zA-z.""
- Zastąp dopasowane znaki znakiem „”źródło
Próbować:
s = ''.join(filter(str.isalnum, s))
Spowoduje to pobranie każdego znaku z łańcucha, zachowanie tylko znaków alfanumerycznych i zbudowanie z nich łańcucha.
źródło
Najszybszą metodą jest regex
#Try with regex first t0 = timeit.timeit(""" s = r2.sub('', st) """, setup = """ import re r2 = re.compile(r'[^a-zA-Z0-9]', re.MULTILINE) st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+' """, number = 1000000) print(t0) #Try with join method on filter t0 = timeit.timeit(""" s = ''.join(filter(str.isalnum, st)) """, setup = """ st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+' """, number = 1000000) print(t0) #Try with only join t0 = timeit.timeit(""" s = ''.join(c for c in st if c.isalnum()) """, setup = """ st = 'abcdefghijklmnopqrstuvwxyz123456789!@#$%^&*()-=_+' """, number = 1000000) print(t0) 2.6002226710006653 Method 1 Regex 5.739747313000407 Method 2 Filter + Join 6.540099570000166 Method 3 Join
źródło
Zaleca się użycie modułu PyPi
regex
, jeśli planujesz dopasować określone klasy właściwości Unicode. Ta biblioteka okazała się również bardziej stabilna, szczególnie w przypadku dużych tekstów i zapewnia spójne wyniki w różnych wersjach języka Python. Wszystko, co musisz zrobić, to dbać o jego aktualność.Jeśli ją zainstalujesz (używając
pip intall regex
lubpip3 install regex
), możesz użyćimport regex print ( regex.sub(r'\P{L}+', '', 'ABCŁąć1-2!Абв3§4“5def”') ) // => ABCŁąćАбвdef
aby usunąć wszystkie fragmenty 1 lub więcej znaków innych niż litery Unicode z
text
. Zobacz demo online Pythona . Możesz również użyć,"".join(regex.findall(r'\p{L}+', 'ABCŁąć1-2!Абв3§4“5def”'))
aby uzyskać ten sam wynik.W Pythonie
re
, aby dopasować dowolną literę Unicode, można użyć[^\W\d_]
konstrukcji ( Dopasować dowolną literę Unicode? ).Tak więc, aby usunąć wszystkie znaki niebędące literami, możesz dopasować wszystkie litery i dołączyć do wyników:
result = "".join(re.findall(r'[^\W\d_]', text))
Lub usuń wszystkie znaki inne niż dopasowane do
[^\W\d_]
:result = re.sub(r'([^\W\d_])|.', r'\1', text, re.DOTALL)
Zobacz demo wyrażenia regularnego online . Jednak możesz uzyskać niespójne wyniki w różnych wersjach Pythona, ponieważ standard Unicode ewoluuje, a zestaw dopasowanych znaków
\w
będzie zależał od wersji Pythona. Zaleca się korzystanie zregex
biblioteki PyPi, aby uzyskać spójne wyniki.źródło