Coincide con el espacio en blanco pero no con líneas nuevas

A veces quiero coincidir con el espacio en blanco pero no con la línea nueva.

Hasta ahora he estado recurriendo a [ \t] . ¿Hay alguna manera menos incómoda?

Las versiones de Perl 5.10 y posteriores admiten clases secundarias de caracteres verticales y horizontales, \v \h , así como también la clase de caracteres generics de espacios en blanco \s

La solución más limpia es usar la clase de caracteres horizontales en blanco \h . Esto coincidirá con la pestaña y el espacio del conjunto ASCII, el espacio sin interrupción desde ASCII extendido, o cualquiera de estos caracteres 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 

El patrón de espacio vertical \v es menos útil, pero coincide con estos caracteres

 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 

Hay siete caracteres verticales en blanco que coinciden con \v dieciocho horizontales que coinciden con \h . \s coincide con veintitrés caracteres

Todos los espacios en blanco son verticales u horizontales sin superposición, pero no son subconjuntos propios porque \h también coincide con U + 00A0 NO-BREAK SPACE, y \v también coincide con U + 0085 NEXT LINE, ninguno de los cuales coincide con \s

Use un doble negativo:

 /[^\S\n]/ 

Para evitar las diferencias de plataforma advertidas en el perlport con respecto a las asignaciones de \r \n :

 /[^\S\x0a\x0d]/ 

Es decir, not-not-whitespace o not-newline y similar para el patrón que excluye CR y NL.

Distribuyendo el exterior no ( es decir , el complemento ^ en la clase de carácter) con la ley de De Morgan , esto es equivalente a “espacio en blanco y no retorno de carro y no nueva línea”, pero no tomes mi palabra:

 #! /usr/bin/env perl use strict; 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"; } 

Salida:

  "" => partido
 "\ f" => partido
 "\ t" => coincidencia
 "\ r" => sin coincidencia
 "\ n" => sin coincidencia 

Tenga en cuenta la exclusión de la pestaña vertical, pero esto se trata en v5.18 .

Este truco también es útil para combinar caracteres alfabéticos. Recuerde que \w coincide con “caracteres de palabras”, caracteres alfabéticos, pero también con dígitos y guiones bajos. Nosotros feos: los estadounidenses a veces quieren escribirlo como, por ejemplo,

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

pero una clase de carácter doblemente negativa puede respetar la configuración regional:

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

Eso es un poco opaco, por lo que una clase de caracteres POSIX puede ser mejor para express el bash

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

o como szbalint sugirió

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

Una variación de la respuesta de Greg que incluye retornos de carro también:

 /[^\S\r\n]/ 

Esta expresión regular es más segura que /[^\S\n]/ sin \r . Mi razonamiento es que Windows usa \r\n para líneas nuevas, y Mac OS 9 usa \r . Es poco probable que encuentre \r sin \n hoy en día, pero si lo encuentra, no podría significar nada más que una nueva línea. Por lo tanto, como \r puede significar una nueva línea, debemos excluirla también.

Lo que estás buscando es la clase de caracteres en blank POSIX. En Perl se hace referencia como:

 [[:blank:]] 

en Java (no olvides habilitar UNICODE_CHARACTER_CLASS ):

 \p{Blank} 

Comparado con el \h similar, el blank POSIX es soportado por algunos motores de expresiones regulares más ( referencia ). Un beneficio importante es que su definición se fija en el Anexo C: Propiedades de compatibilidad de expresiones regulares Unicode y estándar en todos los sabores de expresiones regulares que admiten Unicode. (En Perl, por ejemplo, \h elige incluir adicionalmente el MONGOLIAN VOWEL SEPARATOR ). Sin embargo, un argumento a favor de \h es que siempre detecta caracteres Unicode (incluso si los motores no están de acuerdo con cuál), mientras que POSIX las clases de caracteres suelen ser, por defecto, solo ASCII (como en Java).

Pero el problema es que incluso seguir con Unicode no resuelve el problema al 100%. Considere los siguientes caracteres que no se consideran espacios en blanco en Unicode:

El separador vocálico de vocales antes mencionado no está incluido por lo que probablemente sea una buena razón. Esto, junto con 200C y 200D, ocurre dentro de las palabras (AFAIK), y por lo tanto rompe la regla cardinal de que todos los demás espacios en blanco obedecen: puedes tokenizar con él. Son más como modificadores. Sin embargo, ZERO WIDTH SPACE , WORD JOINER y ZERO WIDTH NON-BREAKING SPACE (si se usa como una marca que no sea de orden de bytes) se ajustan a la regla de espacio en blanco en mi libro. Por lo tanto, los incluyo en mi clase horizontal de caracteres en blanco.

En Java:

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

La expresión regular a continuación coincidiría con los espacios en blanco, pero no con un nuevo carácter de línea.

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

MANIFESTACIÓN

Si desea agregar el retorno del carro, también agregue \r con | operador dentro del lookahead negativo.

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

MANIFESTACIÓN

Agregue + después del grupo sin captura para que coincida con uno o más espacios en blanco.

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

MANIFESTACIÓN

No sé por qué ustedes no mencionaron la clase de caracteres POSIX [[:blank:]] que coincide con cualquier espacio en blanco horizontal ( espacios y tabs ). Esta clase de caracteres POSIX funcionaría en BRE ( Expresiones Regulares Básicas ), ERE ( Expresión Regular Extendida ), PCRE ( Expresión Regular Compatible Perl ).

MANIFESTACIÓN

m/ /g solo da espacio en / / , y funcionará. O use \S : reemplazará todos los caracteres especiales como tabulación, saltos, espacios, etc.