Sie finden "einen Buchstaben, der angezeigt wird, zweimal die" in einem string
Ich versuche, mich zu fangen, wenn Sie einen Buchstaben, der angezeigt wird, zweimal in einem string mittels RegEx (oder vielleicht gibt es einige bessere Möglichkeiten?), zum Beispiel mein string ist:
ugknbfddgicrmopn
Die Ausgabe wäre:
dd
Jedoch, ich habe versucht, so etwas wie:
re.findall('[a-z]{2}', 'ugknbfddgicrmopn')
aber in diesem Fall, es gibt:
['ug', 'kn', 'bf', 'dd', 'gi', 'cr', 'mo', 'pn'] # the except output is `['dd']`
Ich habe auch einen Weg, um das erwarten Ausgabe:
>>> l = []
>>> tmp = None
>>> for i in 'ugknbfddgicrmopn':
... if tmp != i:
... tmp = i
... continue
... l.append(i*2)
...
...
>>> l
['dd']
>>>
Aber das ist zu Komplex...
Wenn es 'abbbcppq'
, dann nur zu fangen:
abbbcppq
^^ ^^
Also die Ausgabe ist:
['bb', 'pp']
Dann, wenn es 'abbbbcppq'
, fangen bb
zweimal:
abbbbcppq
^^^^ ^^
Also die Ausgabe ist:
['bb', 'bb', 'pp']
- Sie können Rückverweis,
([a-z])\1
- Sie scheinen zu erwarten-aber nicht erwähnen -- Kontiguität, und Sie nicht erklären, was würde Sie wollen, wie ein Ergebnis, wenn
"ddd"
vorhanden waren. - was, wenn der Brief erscheint mehr als zwei mal>?
- was, wenn er will diejenigen finden, die erscheint, genau zwei? wie fetch
dd
ausfddf
nicht ausfdddf
- Sie benötigen findall für mehr als ein vorkommen.
re.search('([a-z])\1', 'ugknbfddgicrmopn').group()
- Das war eine Vermutung, die Nicht vertraut mit Python 🙁
- Huh? Getestet auf Python 2.7 und Python 3.5, beide erhöhen
AttributeError: 'NoneType' object has no attribute 'group'
. - was wäre deine erwartete Ausgabe, wenn die Eingabe
abbbbcppq
- Sicher, fangen
bb
zweimal, so ist es['bb', 'bb', 'pp']
. - Meinst du Brief erscheint zweimal die gemeinsam oder überall in input?
- Naja, gemeinsam in diesem Fall.
- Ganz Ähnlich wie [python]: verwenden Sie re zu finden fortlaufend wiederholt chars
Du musst angemeldet sein, um einen Kommentar abzugeben.
Benötigen Sie einfangen Gruppe basiert regex und definieren Sie Ihre regex als raw-string.
oder
Beachten Sie, dass
re.findall
hier sollte die Rückkehr der Liste von Tupeln, mit der die Zeichen, die aufeinander abgestimmt sind, indem die erste Gruppe, die als erstes element und der zweiten Gruppe als zweite element. Für unseren Fall chars innerhalb der ersten Gruppe wäre genug, also habe ich erwähnti[0]
.([a-z])
fangen die ersten Buchstaben, und\1
wiederholen. 🙂()
genannt-capturing-group. So([a-z])
fängt der erste Buchstabe und die folgenden\1
ist ein back-Zitat der ersten capturing group. So\1
bezeichnet alle Zeichen, die aufeinander abgestimmt sind, die von der ersten Gruppe.Als Pythonic way können Sie
zip
Funktion innerhalb einer list comprehension:Wenn Sie sind den Umgang mit großen Zeichenfolge, die Sie verwenden können
iter()
- Funktion konvertieren Sie die Zeichenfolge in einen iterator und Verwendungitertols.tee()
für die Erstellung von zwei unabhängigen iterator, dann durch den Aufruf dernext
Funktion, die auf dem zweiten iterator verbrauchen das erste Element und verwenden Sie diezip
Klasse (in Python 2.X verwenden Sieitertools.izip()
gibt einen iterator) mit dieser Iteratoren.Benchmark mit
RegEx
Rezept:Nach deinem letzten edit, wie oben im Kommentar, wenn Sie möchten, um nur mit ein paar
b
in Zeichenfolgen wie"abbbcppq"
können Siefinditer()
gibt einen iterator der gefundenen Objekte, und extrahieren Sie das Ergebnis mitgroup()
Methode:Beachten Sie, dass
re.I
ist die IGNORECASE fahne, die macht der RegEx-match die Großbuchstaben auch.bb
ausabbbc
. Okay, ich weiß, dass dies ist eine kurze version von mir noch ein Beispiel und das Beispiel von mir ist die Ausgabe nicht das erwarten von meinem edit...sorry about that...set
, dann kann es nicht fangenbb
zweimal, wie ich sagte, in den Kommentaren meine Frage.zip()
: Dregex
ist nicht pythonic an alle, die Kasse bec=nchmark Ergebnis.abbbc
(z.B.['bb']
für die regexp-vs['bb', 'bb']
für diesen code).Mit zurück Referenz, es ist sehr einfach:
Weitere Informationen können Sie beziehen sich auf eine ähnliche Frage in perl: Regulären Ausdruck passen zu jedem Charakter wiederholt mehr als 10 mal
\1{1,}
würde so geschrieben werden, als\1+
Ist es ziemlich einfach, die ohne reguläre Ausdrücke:
abbbbcppq
. Vielleicht ist das problem da, dassif v == 2
🙂[k for k, v in collections.Counter("abbbbcppq").items() if v>1]
tun.Vielleicht kann man den generator um dies zu erreichen
"oder vielleicht gibt es einige bessere Möglichkeiten"
Da regex wird oft missverstanden von den nächsten Entwickler zu begegnen, Ihren code (vielleicht sogar Sie),
Und da einfacher != kürzer,
Wie etwa der folgende pseudo-code:
ffff
, dann würde der Ausgang sein['dd', 'ss', 'ff', 'ff', 'ff']
.'ff', 'ff'
wie gesagt in den Kommentaren.re.search
das funktioniert nur für string.String
nichtlist
.