Ich habe diese Saite
circle,4.5
square,3.1
circle,2.0
triangle,4.7,4.9
square,4.1
circle,4.3
Nehmen wir an, ich möchte den Namen der Form und die beiden Zahlen daneben erfassen. Ich habe es versucht und werde das Problem kommentieren, das ich darin habe:
>>> ma = re.search(r"(\w+)[,(\d+.\d+)]+", "Triangle,3.4,1.2")
>>> ma.group()
'Triangle,3.4,1.2'
>>> ma.group(1)
'Triangle'
>>> ma.group(2) ##Why is this happening ???
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
ma.group(2)
IndexError: no such group
Ich denke, ich kann keine Erfassungsgruppen in eckige Klammern setzen?
3 Antworten
Eckige Klammern sind etwas Besonderes. Sie markieren alle Zeichen in ihnen als Zeichengruppe. Sie möchten entweder eine Zahl (\d
), ein ,
Komma, einen .
Punkt, eine (
öffnende Klammer oder eine )
schließende Klammer finden . Mit anderen Worten, die öffnende und schließende Klammer sind Teil der übereinstimmenden Zeichen, nicht bezeichnet eine Erfassungsgruppe.
Sie müssen hier überhaupt keine Zeichenklasse verwenden, sondern suchen nach einem spezifischeren Zahlenmuster, das von einem Punkt gefolgt von einer anderen Zahl begleitet wird. Verwenden Sie eine nicht erfassende Gruppe ((?:...)
), um das Zahlenformat zusammen mit dem Komma so zu gruppieren, dass es sich wiederholenden Zahlengruppen entspricht:
r"(\w+)(?:,(\d+.\d+))+"
Leider wird dadurch immer noch nicht mehr als eine Gruppe für Sie erfasst. Reguläre Ausdrücke erzeugen niemals eine variable Anzahl von Gruppen. Wir haben hier nur zwei Gruppen definiert, das ist alles, was wir bekommen:
>>> import re
>>> ma = re.search(r"(\w+)(?:,(\d+.\d+))+", "Triangle,3.4,1.2")
>>> ma.groups()
('Triangle', '1.2')
Siehe Regex-Frage zur Parsing-Methodensignatur und Python-Regex-Wiederholung mit Erfassungsfrage für andere SO-Fragen, die unter diese Einschränkung fallen.
Ihr Format ist eigentlich sehr einfach, und Sie sind viel besser dran, wenn Sie überhaupt keine regulären Ausdrücke verwenden. Einfach durch das ,
Komma teilen und fertig:
>>> "Triangle,3.4,1.2".split(',')
['Triangle', '3.4', '1.2']
Die Verwendung von .split(',')
ist der einfachste Weg. Wenn Sie jedoch Regex verwenden möchten, sollten Sie verwenden
ma = re.search(r"^([^,]+),([^,]+)(?:,([^,]+))?", "Triangle,3.4,1.2")
Eckige Klammern haben eine besondere Bedeutung. Sie sollen Character class
erstellen. Wenn Sie also capture groups
in eckige Klammern setzen, bedeutet dies, dass Gruppe1 oder Gruppe2 oder Gruppe3 übereinstimmen. Es stimmt nicht überein Alle Gruppen in Kontinuität. Sie müssten anstelle der eckigen Klammer ein anderes capture group
verwenden.
Für diesen Fall können Sie jedoch einfach split verwenden: -
>>> str = "Triangle,3.4,1.2"
>>> str.split(",")
['Triangle', '3.4', '1.2']
>>>
>>> str = "circle,4.5"
>>> str.split(",")
['circle', '4.5']
>>> str.split(",")[0]
'circle'
>>> str.split(",")[1]
'4.5'
Gemäß Ihrer Regex: -
ma = re.search(r"(\w+)[,(\d+.\d+)]+", "Triangle,3.4,1.2")
Sie verwenden den Zeichensatz [,(\d+.\d+)]
, der mit - ,
oder (\d+.\d+)
übereinstimmt.
Sie sollten es ändern in: -
ma = re.search(r"(\w+)(,(\d+.\d+))+", "Triangle,3.4,1.2")
In diesem Fall gibt es jedoch ein Problem:
Sie haben nur 3 Gruppen erstellt: -
group 0 -> complete match
group 1 -> `,1.2` (Outer bracket)
group 2 -> `1.2` (Inner Bracket)
Sie erhalten 3.4
nicht, weil (,(\d+.\d+))
zuerst übereinstimmt - ,3.4
und dann ,1.2
. Es werden also nur ,1.2
gespeichert.
Verwandte Fragen
Neue Fragen
python
Python ist eine dynamisch typisierte Mehrzweck-Programmiersprache mit mehreren Paradigmen. Es wurde entwickelt, um schnell zu lernen, zu verstehen, zu verwenden und eine saubere und einheitliche Syntax durchzusetzen. Bitte beachten Sie, dass Python 2 ab dem 01.01.2020 offiziell nicht mehr unterstützt wird. Fügen Sie für versionenspezifische Python-Fragen das Tag [python-2.7] oder [python-3.x] hinzu. Wenn Sie eine Python-Variante (z. B. Jython, PyPy) oder eine Bibliothek (z. B. Pandas und NumPy) verwenden, fügen Sie diese bitte in die Tags ein.