Zmagam się z oddzieleniem danego ciągu znaków foobar123 między słowem a cyfrą o nieznanej długości z podkreśleniem (Wynik: foobar_123). Próbowałem użyć wyrażenia regularnego, aby znaleźć dopasowanie r1 (działa). Ale po tym nie mam pojęcia, jak oddzielić odpowiedni mecz.

import re
x = "foobar123"
y = re.sub("[a-z]{1}\d{1}", "\1", x)
print(y) # Output: "fooba23"

Myślę, że powinno to być zrobione z "\ 1", aby uzyskać dostęp do poprzedniego dopasowania. Próbowałem więc zastąpić znalezione dopasowanie samym sobą, ale to daje: fooba23. Czy nie powinien to być foobar123.

Z góry dziękuję.

AKTUALIZACJA:

Przepraszamy za literówkę w powyższym kodzie, powinno to być [a-z] a nie [0-9].

2
Habebit 3 kwiecień 2020, 13:06

4 odpowiedzi

Najlepsza odpowiedź

Możesz

  • przechwycił literę w jednej części, a cyfry w drugiej: ([a-z]+)([0-9]+)
  • zamień na grupę liter, podkreślenia, cyfr: \1_\2

Dodałem re.I dla ignorecase

x = "Foobar123"
y = re.sub("([a-z]+)([0-9]+)", r"\1_\2", x, flags=re.I)
print(y)  # Foobar_123
1
azro 3 kwiecień 2020, 11:17

To może załatwić sprawę, używając grupy przechwytywania twoich cyfr?

import re
x = "foobar123"
y = re.sub(r'(\d+)', r'_\1', x)
print(y)

Uniknąłem ukośników za pomocą surowego sznurka. Coś, o czym zapomniałeś zrobić w swoim =)


Zabawną alternatywą bez grupy przechwytującej jest użycie count parametr re.sub:

import re
x = "foobar123"
y = re.sub(r'(?=\d)', '_', x, 1)
print(y)

Wzorzec (?=\d) zwraca wszystkie pozycje, po których następuje cyfra, ale tylko pierwsza (stąd 1 dla count) zostaje zastąpiona podkreśleniem.

6
JvdV 3 kwiecień 2020, 11:27

Możesz uchwycić ostatnią literę, po której następuje cyfra i dołączyć podkreślenie:

re.sub(r'([a-z])(?=\d)', r'\1_', x)
# 'foobar_123'
2
yatu 3 kwiecień 2020, 10:11

Dopasowujesz 2 cyfry za pomocą [0-9]{1}\d{1}, gdzie {1} nie jest potrzebne, a znak a-z przed cyframi nie jest brany pod uwagę.

Możesz dokonać zamiany bez grupy przechwytującej, używając tylko dopasowania \g<0>, po którym następuje podkreślenie.

Wzorzec dopasuje znak [a-z] i używa dodatniego lookahead (?=\d), aby stwierdzić, że to, co jest po prawej stronie, jest cyfrą.

import re
x = "foobar123"
y = re.sub("[a-z](?=\d)", "\g<0>_", x)
print(y) # Output: "foobar_123"
2
The fourth bird 3 kwiecień 2020, 10:35