Faire correspondre les espaces mais pas les nouvelles lignes

Je veux parfois correspondre à des espaces mais pas à une nouvelle ligne.

Jusqu’à présent, j’ai eu recours à [ \t] . Y a-t-il une manière moins délicate?

Les versions Perl 5.10 et ultérieures prennent en charge les classes de caractères verticales et horizontales subsidiaires, \v et \h , ainsi que la classe de caractères générique des espaces blancs

La solution la plus propre consiste à utiliser la classe horizontale des caractères blancs \h . Cela fera correspondre les tabulations et les espaces de l’ensemble 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 motif d’ espace vertical \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 horizontaux qui correspondent à \h . \s correspond à vingt-trois personnages

Tous les caractères d’espacement sont verticaux ou horizontaux sans chevauchement, mais ils ne sont pas des sous-ensembles appropriés car \h correspond également à U + 00A0 NO-BREAK SPACE et \v correspond également à U + 0085 NEXT LINE, dont aucun ne correspond à \s

Utilisez un double négatif:

 /[^\S\n]/ 

Pour éviter les différences de plate-forme mises en garde dans perlport concernant les mappages de \r et \n :

 /[^\S\x0a\x0d]/ 

C’est-à-dire pas non-blanc ou non-nouvelle ligne et similaire pour le modèle qui exclut CR et NL.

Dissortingbuer l’extérieur non ( c’est-àdire le complément ^ dans la classe de caractères) avec la loi de De Morgan , cela équivaut à «blanc et non pas retour à la ligne et non pas à la ligne», mais ne le croyez pas:

 #! /usr/bin/env perl use ssortingct; use warnings; use 5.005; # for qr// my $ws_not_nl = qr/[^\S\x0a\x0d]/; for (' ', '\f', '\t', '\r', '\n') { my $qq = qq["$_"]; printf "%-4s => %s\n", $qq, (eval $qq) =~ $ws_not_nl ? "match" : "no match"; } 

Sortie:

  "" => match
 "\ f" => match
 "\ t" => correspond
 "\ r" => pas de correspondance
 "\ n" => pas de correspondance 

Notez l’exclusion de l’onglet vertical, mais cela est traité dans la v5.18 .

Cette astuce est également pratique pour faire correspondre des caractères alphabétiques. Rappelez-vous que \w correspond aux “caractères de mots”, aux caractères alphabétiques, mais aussi aux chiffres et au trait de soulignement. Nous, les Américains laids veulent parfois l’écrire comme, disons,

 if (/^[A-Za-z]+$/) { ... } 

mais une classe de caractères double-négative peut respecter les parameters régionaux:

 if (/^[^\W\d_]+$/) { ... } 

C’est un peu opaque, donc une classe de caractères POSIX peut mieux exprimer l’intention

 if (/^[[:alpha:]]+$/) { ... } 

ou comme szbalint suggéré

 if (/^\p{Letter}+$/) { ... } 

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

 /[^\S\r\n]/ 

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

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

 [[:blank:]] 

en Java (n’oubliez pas d’activer UNICODE_CHARACTER_CLASS ):

 \p{Blank} 

Comparé à un environnement similaire, POSIX blank est supporté par quelques autres moteurs de regex ( référence ). Un avantage majeur est que sa définition est fixée dans l’ Annexe C: Propriétés de compatibilité des expressions régulières Unicode et standard sur toutes les versions 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 sont pas d’accord), alors que POSIX Les classes de caractères 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érons les caractères suivants qui ne sont pas considérés comme des espaces dans Unicode:

Le séparateur de voyelle mongole susmentionné n’est pas inclus pour une raison probable. Elle, avec 200C et 200D, se trouve à l’intérieur des mots (AFAIK), et rompt donc avec la règle cardinale que tous les autres espaces blancs obéissent: vous pouvez numériser avec elle. Ils sont plus comme des modificateurs. Cependant, ZERO WIDTH SPACE , WORD JOINER et ZERO WIDTH NON-BREAKING SPACE (s’il ne s’agissait pas d’une marque d’ordre d’octet) correspondaient à la règle d’espacement de mon livre. Par conséquent, je les inclut dans ma classe de caractères d’espace horizontal.

En Java:

 static public final Ssortingng HORIZONTAL_WHITESPACE = "[\\p{Blank}\\u200B\\u2060\\uFFEF]" 

Le regex ci-dessous correspondrait aux espaces blancs mais pas à un nouveau caractère de ligne.

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

DEMO

Si vous voulez append un retour chariot, ajoutez \r avec le | opérateur à l’intérieur de la tête de lecture négative.

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

DEMO

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

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

DEMO

Je ne sais pas pourquoi vous n’avez pas mentionné la classe de caractères POSIX [[:blank:]] qui correspond à tous les espaces horizontaux ( espaces et tabulations ). Cette classe de caractères POSIX fonctionnerait sur BRE ( Basic REgular Expressions ), ERE ( Extended Regular Expression ), PCRE ( expression régulière compatible Perl ).

DEMO

m/ /g donne juste de la place dans / / , et ça va marcher. Ou utilisez \S – il remplacera tous les caractères spéciaux comme tab, newlines, spaces, etc.