2015-11-13 17 views
5

Załóżmy, że mam ten fragment tekstu:Aby wymienić ale ostatnie wystąpienie ciągu znaków w tekście

Saturday and Sunday and Monday and Tuesday and Wednesday and Thursday and Friday are days of the week. 

chcę wszystko oprócz ostatniego and zastępuje się przecinkiem:

Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday and Friday are days of the week. 

Czy istnieje prosty sposób to zrobić w regex? O ile mi wiadomo, metodaw regex zastępuje ciągi przez cały czas.

+4

Nie używam przecinka Oxford, widzę. –

+0

Ściśle mówiąc, wyrażenia regularne wykonują tylko dopasowywanie, a podstawienie jest cechą języka hostingu, zwykle jest to proces przetwarzania ciągów znaków. – tripleee

+0

To jest trochę nieczytelne. Może mógłbyś się z tym zabawić. "" .join (zmniejsz (lambda x, y: x + ["i" + y], jeśli len (x) == 0 else x + ["," + y], re.split ("i", "sobota a niedziela i poniedziałek i wtorek oraz środa i czwartek i piątek są dniami tygodnia. ") [:: - 1], []) [:: - 1]) [1:] –

Odpowiedz

15

str.replace() metoda ma count argumentu:

str.replace(old, new[, count])

zwrócić kopię napisu z wszystkimi wystąpieniami podciągu stare zastąpione nowymi. Jeśli podana jest opcjonalna liczba argumentów, zastępowane są tylko wystąpienia pierwszych liczników.

Następnie użyj str.count() aby sprawdzić, ile and w łańcuchu, a następnie -1 (bo trzeba ostatni and):

str.count(sub[, start[, end]])

Powrót liczba non-nakładających się wystąpień podłańcuch sub w zakresie [start, end]. Opcjonalne argumenty start i end są interpretowane tak jak w notacji plasterka.

Demo:

>>> string = 'Saturday and Sunday and Monday and Tuesday and Wednesday and Thursday and Friday are days of the week.' 
>>> string.replace(' and ', ", ", (string.count(' and ')-1)) 
'Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday and Friday are days of the week. ' 
4

Jeśli chcesz rozwiązanie regex, można dopasować wszystkie and s, które są stosowane przez innego później w ciągu.

>>> str='Monday and Tuesday and Wednesday and Thursday and Friday and Saturday and Sunday are the days of the week.' 
>>> import re 
>>> re.sub(' and (?=.* and)', ', ', str) 
'Monday, Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday are the days of the week.' 

(?= ... ) jest uprzedzona, który pilnuje tam (nie tak również w substytucji) jest mecz w dalszej części łańcucha bez włączania go w rzeczywistej meczu. To coś w rodzaju warunku na meczu.

+0

Co stanie się z tym ciągiem:' "Poniedziałek i wtorek oraz środa, czwartek, piątek, sobota i niedziela to dni tygodnia, a jest poniedziałek." "? – IanAuld

+0

Łatwo się o tym przekonać, prawda? Może zmienić '. *' W wczytaniu na '[^.?!] *', Aby nigdy nie pozwalać na dopasowanie interpunkcji w zdaniu poprzednim. Ale w jaki sposób radzisz sobie ze skrótami zdań w drugim zdaniu z okresem, który nie jest terminatorem zdań? Szybko kończysz z [problemem Zawińskiego] (http://programmers.stackexchange.com/questions/223634/what-is-meant-by-now-you-have-two-problems). Dla czegoś poza prostymi tokenami, regex prawdopodobnie nie jest odpowiednim narzędziem. – tripleee

+0

Ale w przypadku tego prostego problemu prawdopodobnie mógłbyś ograniczyć to jeszcze bardziej i mieć nadzieję, że nigdy nie dopasuje się do czasownika."John i Mary i poszliśmy do Pałacu Buckingham i napiliśmy się piwa." – tripleee

Powiązane problemy