Je reçois une ligne de chaîne:

>>> line = "  abc\n  def\n\n  ghi\n  jkl"
>>> print line
  abc
  def

  ghi
  jkl

Et je veux le convertir en "abcdef \ n \ n ghijkl", comme:

>>> print "  abcdef\n\n  ghijkl"
  abcdef

  ghijkl

J'ai essayé le module python re, et j'écris quelque chose comme ceci:

re.sub('(?P<word1>[^\n\s])\n\s*(?P<word2>[^\n\s])', '\g<word1>\g<word2>', line)

Mais je reçois ceci:

>>> re.sub('(?P<word1>[^\n\s])\n\s*(?P<word2>[^\n\s])', '\g<word1>\g<word2>', line)
Out: '  abcdefghijkl'

Il me semble que la partie \n\s* correspond également à \n\n. Quelqu'un peut-il indiquer où je me trompe?

2
lxyu 5 déc. 2011 à 21:49

3 réponses

Meilleure réponse

\s correspond à l'espace, \t, \n (et, selon votre moteur d'expression régulière), quelques autres caractères d'espacement.

Donc, si vous souhaitez uniquement remplacer les sauts de ligne + espaces / tabulations, vous pouvez utiliser ceci:

newline = re.sub(r"(?<!\n)\n[ \t]*(?!\n)", "", line)

Explication:

(?<!\n) # Assert that the previous character isn't a newline
\n      # Match a newline
[ \t]*  # Match any number of spaces/tabs
(?!\n)  # Assert that the next character isn't a newline

En Python:

>>> line = "  abc\n  def\n\n  ghi\n  jkl"
>>> newline = re.sub(r"(?<!\n)\n[ \t]*(?!\n)", "", line)
>>> print newline
  abcdef

  ghijkl
4
Tim Pietzcker 5 déc. 2011 à 17:58

Essaye ça,

line = "  abc\n  def\n\n  ghi\n  jkl"
print re.sub(r'\n(?!\n)\s*', '', line)

Il donne,

abcdef
ghijkl

Il dit: "Remplacez une nouvelle ligne, suivie d'un espace qui n'est PAS une nouvelle ligne avec rien."

MISE À JOUR: Voici une meilleure version

>>>  re.sub(r'([^\n])\n(?!\n)\s*', r'\1', line)
'  abcdef\n\n  ghijkl'

Il donne exactement ce que vous avez dit dans le premier post.

0
Brigand 5 déc. 2011 à 18:01

Vous pouvez simplifier l'expression régulière si vous avez utilisé \S, qui correspond à tout caractère non blanc:

>>> import re
>>> line = "  abc\n  def\n\n  ghi\n  jkl"
>>> print re.sub(r'(\S+)\n\s*(\S+)', r'\1\2', line)
  abcdef

  ghijkl

Cependant, la raison pour laquelle votre propre expression rationnelle ne fonctionne pas est que vos groupes <word1> et <word2> ne correspondent qu'à un seul caractère (c'est-à-dire qu'ils n'utilisent pas +). Donc, avec cette simple correction, votre expression régulière produira la sortie correcte:

>>> print re.sub(r'(?P<word1>[^\n\s]+)\n\s*(?P<word2>[^\n\s]+)', r'\g<word1>\g<word2>', line)
  abcdef

  ghijkl
0
ekhumoro 5 déc. 2011 à 18:14
8389593