Je suis sûr que cela a déjà été demandé, mais je ne peux pas le trouver.
Fondamentalement, en supposant que vous analysiez un fichier texte d'origine inconnue et que vous souhaitiez remplacer les sauts de ligne par un autre délimiteur, est-ce le meilleur regex, ou y en a-t-il un autre?
(\r\n)|(\n)|(\r)
Fletcher - cela a été demandé une fois auparavant.
Ici vous allez: Expression régulière pour correspondre aux caractères de nouvelle ligne multiplateforme
L'expression régulière que j'utilise lorsque je veux être précis est "\ r\n? |\N".
Vérifiez si votre moteur d'expression régulière prend en charge \R
comme une classe de caractères abrégés et vous n'aurez pas besoin de vous préoccuper des différentes combinaisons de saut de ligne/saut de ligne Unicode. Si implémenté correctement, vous pouvez alors faire correspondre toutes les différentes fins de ligne ascii ou Unicode de manière transparente en utilisant \R
.
En Unicode, vous devez détecter NEL
(fin de ligne OS/390,\x85) LS
(séparateur de ligne,\x2028) et PS
(séparateur de paragraphe,\x2029) si vous voulez être complètement multiplateforme ces jours-ci.
On peut se demander si LS, NEL et PS doivent être traités comme des sauts de ligne, des fins de ligne ou des espaces blancs. La norme XML 1.0, par exemple, ne reconnaît pas NEL comme caractère de saut de ligne. ECMAScript traite LS
et PS
comme des sauts de ligne mais NEL
comme des espaces. Perl unicode les expressions régulières traiteront VT
, FF
, CR
, CRLF
, NEL
, LS
et PS
comme sauts de ligne dans le but de ^
et $
caractères méta regex.
Le nicode Implementation Guide (section 5.8 et tableau 5.3) est probablement le meilleur pari de ce qu'est le traitement définitif de ce qu'est une "nouvelle ligne".
Si vous êtes uniquement concerné par ascii avec les variantes classiques DOS/Windows/Unix/Mac, le regex équivalent à \R
est (?>\r\n|[\r\n])
En Unicode, l'équivalent de \R
est (?>\r\n|\n|\x0b|\f|\r|\x85|\x2028|\x2029)
Le \x0b
il y a un onglet vertical; encore une fois, cela peut ou non correspondre à votre définition de ce qu'est un saut de ligne, mais cela correspond à la recommandation de l'implantation Unicode. (FF
ou \x0C
n'est pas inclus dans l'expression régulière car un flux de formulaire est une nouvelle page, pas une nouvelle ligne dans la définition.)
Le regex pour trouver un terminateur de ligne Unicode doit être (?>\x0D\x0A?|[\x0A-\x0C\x85\x{2028}\x{2029}])
plutôt que comme l'a écrit Drewk, du moins en Perl. Tiré directement de la documentation Perl 5.10.0 (il a été supprimé dans les versions ultérieures). Notez les accolades après \x
: U + 2029 est \x{2029}
mais \x2029
est un ASCII espace blanc (U + 0020) + un chiffre 2 + un chiffre 9. \n
en dehors d'une classe de caractères, il n'est pas non plus garanti de correspondre à \x{0a}
.
Si votre plate-forme ne prend pas en charge le \R
class comme suggéré par @dawg ci-dessus, vous pourrez peut-être encore faire une solution assez élégante et robuste si votre plate-forme prend en charge la soustraction négative lookaround ou la classe de caractères (par exemple dans Java la soustraction de classe se fait par syntaxe[x&&[^y]]
).
Dans la plupart des grammaires d'expression régulières, le caractère point est défini comme signifiant "n'importe quel caractère sauf le caractère de nouvelle ligne" (voir par exemple, pour JavaScript, ici ). Si vous faites correspondre quelque chose avec les caractéristiques suivantes:
Puisque je travaille actuellement en JavaScript, AFAIK n'a pas le \R
sténographie ou soustraction de classe de caractères, je peux toujours utiliser l'anticipation négative pour obtenir ce que je veux. L'expression régulière suivante correspond à toutes les nouvelles lignes:
/((?!.)\s)+/g
Et le code JavaScript suivant, au moins lorsqu'il est exécuté dans Chrome 42.0.2311.90m sur Windows 7, efface tous les types de sauts de ligne que JavaScript (c'est-à-dire le "ECMAScript" mentionné dans le troisième paragraphe de @ dawg ) reconnaît:
var input = "hello\r\n\f\v\u2028\u2029 world";
var output = input.replace(/((?!.)\s)+/g, "");
document.write(output); // hello world
Remplacez simplement /[\r\n]+/g
avec une chaîne vide ""
.
Il remplacera tout \r
et \n
quel que soit l'ordre dans lequel ils apparaissent dans la chaîne.