Der richtige Weg, um mit dem zu verfahren, was Sie versuchen zu tun, ist Capturing Groups zu verwenden. Auf diese Weise können Sie auf Ihre Übereinstimmung verweisen. Lassen Sie mich zunächst erklären, warum Ihr Versuch Ihnen die Ausgabe gab, die Sie gesehen haben.
Warum Sie sah, was du gesehen hast
In der re.sub
Funktion, wenn Sie es ' '+str(pattern)+' '
als dritter Parameter geben, diese auf die Zeichenfolge ausgewertet wird " <_sre.SRE_Pattern object at some_memory_location> "
, weil str(pattern)
die Stringdarstellung des Objekts Muster kehrt, nicht von der Muster.
Nebenbei, auf Python 3.4 und 3.5, str(pattern)
gibt re.compile('[%&\\(\\)\\+,-./:;=–‘’“”″]')
für mich zurück, welche Version von Python verwenden Sie? Ist es vielleicht eine Version von Python 2?
Lösung
Wie ich vor erwähnt, erfordert Ihre Lösung unter Verwendung groups einzufangen. Um eine Gruppe zu bezeichnen, verwenden Sie einfach Klammern. In Ihrem Fall ist die Lösung einfach genug ist, weil Sie nur eine Gruppe benötigen:
>>> import re
>>> pattern = re.compile(r"([%&\(\)\+,-./:;=–‘’“”″]+)")
Hinweis für meinen Stringliteral, benutzen ich ein r
vor Beginn der Zeichenfolge. Dies bezeichnet eine rohe Zeichenfolge, die bewirkt, dass die Zeichenfolge jede Escape-Sequenz ignoriert, wie von Python definiert. Eine Escape-Sequenz ist zum Beispiel eine Art '\t'
, die eine Registerkarte bezeichnet. Wenn Sie jedoch r'\t'
verwenden, ist es die tatsächliche Zeichenfolge \t
.
>>> text = "hi. hi.. hi; hi;; 55% good& good&&"
>>> pattern.sub(r' \1 ', text)
'hi . hi .. hi ; hi ;; 55 % good & good && '
Hinweis habe ich einfach die sub
Methode des Musterobjekt statt der Modulebene Funktion re.sub
. Es ist keine große Sache, aber es scheint mir nur sauberer zu sein. Auch für das Ersetzungsargument verwendete ich r' \1 '
. Diese \1
bezieht sich auf die erste Gruppe von Ihrem Muster erfasst. Wenn Sie mehr als eine Gruppe hatten, könnten Sie etwas wie \2 \1
verwenden, wenn Sie beispielsweise ein Muster umkehren wollten. Das ist wieder eine Escape-Sequenz!
Eine mögliche Verbesserung
Es war unklar, in Ihrer Spezifikation, wie Sie mit mehr als 2 Zeichen behandeln wollten z.B. drei Zeichen. So würde Ihr Muster thusly mit dieser Situation umgehen:
>>> text2 = "hi. hi.. hi; hi;; 55% good& good&& hi &&& hello,"
>>> pattern.sub(r' \1 ', text2)
'hi . hi .. hi ; hi ;; 55 % good & good && hi &&& hello , '
Vielleicht ist das, was Sie was, aber vielleicht möchten Sie prüfen, ‚& & &‘ als zwei verschiedene Begegnungen: ‚& &‘ und ‚&‘. Sie können mit dieser Situation doch mit quantifiers beschäftigen:
>>> pattern2 = re.compile(r'([%&\(\)\+,-./:;=–‘’“”″]{1,2})')
>>> pattern2.sub(r' \1 ', text2)
'hi . hi .. hi ; hi ;; 55 % good & good && hi && & hello , '
Anstatt das +
Zeichen zu verwenden, die ein-oder-mehr bedeutet, können Sie die Klammer-Notation mehr feinkörnige Kontrolle haben. Beispiel: {1,3} entspricht 1 bis 3. {3} entspricht genau 3. {3,} entspricht 3 oder mehr.
Vielen Dank für Ihre freundliche Hilfe. Ich dachte nicht, dass es so einfach ist, mein Problem zu lösen, wie Sie es angemessen erklärt haben. Bezüglich der Python-Version habe ich versucht, es unter 3.3.2 zu implementieren. Ich werde jetzt 3.4 installieren. In Bezug auf den Verbesserungsabschnitt wollte ich mich mit einem oder mehreren, sogar drei Charakteren des gleichen Typs befassen, die als eine Übereinstimmung behandelt werden, und das ist es, was Sie demonstriert haben. Nochmals vielen Dank für Ihre Hilfe. – Mohammed
Allerdings möchte ich die Verwendung von '.sub (r '\ l', ...)' verstehen. – Mohammed
@Mohammed Ah! Ja, das bezieht sich einfach auf die erste Gruppe, die von deinem Muster erfasst wurde! Wenn Sie mehrere Gruppen haben, können Sie auf die dritte als etwas wie 'Dies ist die dritte Gruppe: \ 3' verweisen. Siehe meine Bearbeitung. –