3
votes

Remplacement des parenthèses à l'aide de regex en Python

J'essaye de remplacer la parenthèse autour d'un chiffre ou d'une seule lettre (1), (a) par 1. et 2. Je veux laisser les mots plus longs en place (reprehenderit)

C'est ce que j'ai essayé. Le point complet apparaît des deux côtés de toutes les anciennes parenthèses lorsque je souhaite qu'il n'apparaisse qu'une seule fois.

Merci

Lorem ipsum dolor sit amet,

1. consectetur adipiscing elit, sed do eiusmod tempor incididunt
2. ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
    a. ex ea (commodo consequat). Duis aute irure dolor in (reprehenderit) in voluptate velit esse cillum dolore eu
    b. fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Ce que je reçois:

Lorem ipsum dolor sit amet,

.1. consectetur adipiscing elit, sed do eiusmod tempor incididunt

.2. ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip

.a. ex ea .commodo consequat.. Duis aute irure dolor in .reprehenderit. in voluptate velit esse cillum dolore eu

.b. fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Je cherche:

import re

text = '''Lorem ipsum dolor sit amet,\n\n(1)consectetur adipiscing elit, sed do eiusmod tempor incididunt\n\n(2)ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip\n\n(a) ex ea (commodo consequat). Duis aute irure dolor in (reprehenderit) in voluptate velit esse cillum dolore eu\n\n(b) fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'''

result = re.sub(r'[\(\)]','.\1', text)

Print(result)


4 commentaires

Ces points ne sont pas le seul problème car "\1" est un caractère avec le code octal \001 . Vous avez besoin de quelque chose comme re.sub(r'\(([\da-z]+)\)', r'\1. ', s)


bien sûr. regex peut être difficile à faire. J'ai essayé ceci et cela fonctionne. Merci de votre aide. très appréciée.


Vous n'avez pas de groupe de capture dans votre expression régulière, par quoi espérez-vous que \1 soit remplacé? Vous remplacez simplement tout ( et ) par .


Attendez-vous que le remplacement de l'expression régulière ajoute automatiquement une indentation supplémentaire lorsqu'il correspond à une lettre plutôt qu'à un chiffre?


3 Réponses :


0
votes
result = re.sub(r'\(([0-9a-z])\)', r'\1. ', text)

6 commentaires

Il remplacera toutes les occurrences de, disons, (1992) dans le texte


Il ne doit y avoir qu'une seule lettre entre parenthèses.


@ WiktorStribiżew, ça ne devrait pas?


@Barmar, supprimé +


Maintenant, vous les supprimerez n'importe où dans une chaîne, alors qu'ils ne doivent être mis en correspondance qu'au début d'une ligne


@ WiktorStribiżew, peut-être pouvez-vous m'indiquer où vous avez trouvé l'exigence de ne remplacer les occurrences qu'au début de la ligne?



1
votes

Vous supprimez en fait tout ( et ) avec un point et un caractère avec le code octal \001 .

Si vous souhaitez remplacer (...) au début d'une ligne par une lettre ou un chiffre à l'intérieur, utilisez

result = re.sub(r'^\((\d+|[a-z]+)\)', r'\1. ', text, flags=re.M)

Voir cette démo regex . Notez l'utilisation de ^ qui permet la correspondance au début d'une ligne uniquement (cela fonctionne avec l' flags=re.M ).

Pour supprimer lorsqu'il y a plus de 1 chiffres ou lettres, utilisez

result = re.sub(r'^\(([\da-z])\)', r'\1. ', text, flags=re.M)

Voir la démo regex . Ici,

  • ^ - correspond au début d'une ligne
  • \( - (
  • (\d+|[az]+) - 1 ou plusieurs chiffres ou 1 ou plusieurs lettres
  • \) - a ) car.


0 commentaires

-1
votes

J'ai pris toutes vos réponses et j'ai joué avec elles. J'ai pensé que cela pourrait aider les autres. J'ai toujours du mal avec les regex !! Wiktor Stribiżew m'a orienté dans la bonne direction.

# find all (1), (2) and replace with 1., 2.
re.sub(r'\(([\d])\)', r'\1.  ', text)

# find all (a), (b) and replace with a., b.
re.sub(r'\(([\(a-z)])\)', r'\1.  ', text)

# find both (1), (2), (a), (b) and replace with 1., 2., a., b.
re.sub(r'\(([\da-z])\)', r'\1. ', text)


2 commentaires

Veuillez considérer accepter ma réponse car ma solution s'est avérée efficace pour vous. Vos expressions régulières ici ne sont pas optimales et ne suivent pas les meilleures pratiques, veuillez envisager de supprimer cette "réponse".


Notez que le modèle \(([\(az)])\) est corrompu car le \( dans la classe de caractères est une faute de frappe, ce modèle correspond également à (() . [\d] doit être écrit comme \d , en utilisant un un atome unique dans une classe de caractères rend le modèle moins lisible et peut dérouter les futurs utilisateurs de regex qui pourraient vouloir faire correspondre une séquence de modèles (s'ils mettent quelque chose entre crochets, les caractères ne seront mis en correspondance qu'individuellement, etc.) \(([\da-z])\) est ma suggestion du commentaire mais il peut correspondre trop, car il correspond à n'importe quel endroit de la chaîne alors que vous voulez faire correspondre au début de la ligne.