web-dev-qa-db-fra.com

Correspondre aux espaces mais pas aux nouvelles lignes

Je veux parfois faire correspondre les espaces mais pas les retours à la ligne.

Jusqu'ici, j'ai eu recours à [ \t]. Y a-t-il un moyen moins gênant?

249
JoelFan

Les versions 5.10 et ultérieures de Perl prennent en charge les classes de caractères verticaux et horizontaux subsidiaires, \v et \h, ainsi que la classe générique de caractères d'espaces blancs \s.

La solution la plus propre consiste à utiliser le espace blanc horizontal classe de caractères \h. Cela correspondra à la tabulation et à l'espace du jeu ASCII, à l'espace insécable de l'ASCII étendu ou à l'un de ces caractères Unicode.

U+0009 CHARACTER TABULATION
U+0020 SPACE
U+00A0 NO-BREAK SPACE (not matched by \s)

U+1680 OGHAM SPACE MARK
U+2000 EN QUAD
U+2001 EM QUAD
U+2002 EN SPACE
U+2003 EM SPACE
U+2004 THREE-PER-EM SPACE
U+2005 FOUR-PER-EM SPACE
U+2006 SIX-PER-EM SPACE
U+2007 FIGURE SPACE
U+2008 PUNCTUATION SPACE
U+2009 THIN SPACE
U+200A HAIR SPACE
U+202F NARROW NO-BREAK SPACE
U+205F MEDIUM MATHEMATICAL SPACE
U+3000 IDEOGRAPHIC SPACE

Le espace vertical motif \v est moins utile, mais correspond à ces caractères

U+000A LINE FEED
U+000B LINE TABULATION
U+000C FORM FEED
U+000D CARRIAGE RETURN
U+0085 NEXT LINE (not matched by \s)

U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR

Il y a sept caractères d'espacement verticaux qui correspondent à \v et dix-huit caractères horizontaux qui correspondent à \h. \s correspond à vingt-trois caractères

Tous les caractères d'espacement sont soit vertical ou horizontal sans chevauchement, mais ils ne constituent pas des sous-ensembles appropriés, car \h correspond également à U + 00A0 NO-BREAK SPACE et \v correspond également à U + 0085 NEXT LINE, aucun des deux ne correspondant à \s

160
Borodin

Une variante de réponse de Greg qui inclut également les retours à la ligne:

/[^\S\r\n]/

Cette expression rationnelle est plus sûre que /[^\S\n]/ sans \r. Mon raisonnement est que Windows utilise \r\n pour les nouvelles lignes et que Mac OS 9 a utilisé \r. Il est peu probable que vous trouviez \r sans \n de nos jours, mais si vous le trouvez, il ne peut s’agir que d’une nouvelle ligne. Ainsi, puisque \r peut signifier une nouvelle ligne, nous devrions également l'exclure.

44
Rory O'Kane

Ce que vous recherchez, c'est la classe de caractères POSIX blank. En Perl, il est référencé comme:

[[:blank:]]

dans Java (n'oubliez pas d'activer UNICODE_CHARACTER_CLASS]:

\p{Blank}

Comparé au semblable \h, POSIX blank est supporté par quelques autres moteurs de regex ( reference ). Un avantage majeur réside dans le fait que sa définition est fixée entre Annexe C: Propriétés de compatibilité des expressions régulières Unicode et standard dans tous les types de regex prenant en charge Unicode. (En Perl, par exemple, \h choisit d'inclure en plus le MONGOLIAN VOWEL SEPARATOR.) Cependant, un argument en faveur de \h est qu'il détecte toujours les caractères Unicode (même si les moteurs ne le font pas). pas d’accord sur lequel), alors que les classes de caractères POSIX sont souvent par défaut uniquement ASCII (comme en Java).

Mais le problème est que même s'en tenir à Unicode ne résout pas le problème à 100%. Considérez les caractères suivants qui ne sont pas considérés comme des espaces dans Unicode:

Le séparateur de voyelles mongole mentionné ci-dessus n'est pas inclus pour une bonne raison. Avec 200C et 200D, il se produit dans les mots (autant que je sache) et enfreint par conséquent la règle cardinale à laquelle tous les autres espaces obéissent: vous pouvez créer une marque avec. Ils ressemblent plus à des modificateurs. Cependant, ZERO WIDTH SPACE, Word JOINER et ZERO WIDTH NON-BREAKING SPACE (s'il est utilisé autrement qu'une marque d'ordre des octets) respectent la règle des espaces dans mon livre. Par conséquent, je les inclut dans ma classe de caractères d'espaces blancs horizontaux.

En Java:

static public final String HORIZONTAL_WHITESPACE = "[\\p{Blank}\\u200B\\u2060\\uFFEF]"
11
Aleksandr Dubinsky

L'expression ci-dessous correspond aux espaces, mais pas à un nouveau caractère de ligne.

(?:(?!\n)\s)

DÉMO

Si vous souhaitez également ajouter un retour chariot, ajoutez \r avec l'opérateur | à l'intérieur du signe négatif.

(?:(?![\n\r])\s)

DÉMO

Ajoutez + après le groupe non capturé pour correspondre à un ou plusieurs espaces.

(?:(?![\n\r])\s)+

DÉMO

Je ne sais pas pourquoi vous autres avez omis de mentionner la classe de caractères POSIX [[:blank:]] qui correspond à tous les espaces blancs horizontaux (, espaces et tabulations ). Cette classe de caractères POSIX fonctionnerait sur BRE ( expressions régulières de base ), ERE ( expressions régulières étendues ), PCRE ( Expression régulière compatible avec Perl ).

DÉMO

11
Avinash Raj