Coincidir con espacios en blanco pero no con nuevas líneas


A veces quiero hacer coincidir los espacios en blanco, pero no la nueva línea.

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

 207
Author: Borodin, 2010-08-12

6 answers

Las versiones de Perl 5.10 y posteriores admiten clases subsidiarias de caracteres verticales y horizontales, \v y \h, así como la clase genérica de caracteres en blanco \s

La solución más limpia es usar la clase de caracteres de espacio en blanco horizontal \h. Esto coincidirá con tabulación y espacio del conjunto ASCII, espacio sin interrupción de 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 espacio vertical patrón \v es menos útil, pero coincide 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 y dieciocho horizontales que coinciden con \h. \s coincide con veintitrés caracteres

Todos los caracteres de espacio en blanco son verticales o horizontales sin superposición, pero no son subconjuntos propios porque \h también coincide con U + 00A0 ESPACIO SIN INTERRUPCIÓN, y \v también coincide con U + 0085 LÍNEA SIGUIENTE, ninguno de los cuales coincide con \s

 142
Author: Borodin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-06 12:06:04

Utilice una doble negativa:

/[^\S\n]/

Para evitar diferencias de plataforma advertido en perlport con respecto a las asignaciones de \r y \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 not externo ( es decir, , el complemento ^ en la clase de caracteres) 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 tome mi palabra para ello:

#! /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:

" "  => match
"\f" => match
"\t" => match
"\r" => no match
"\n" => no match

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

Este truco también es útil para emparejar caracteres alfabéticos. Recuerde que \wcoincide con "caracteres de palabra", caracteres alfabéticos pero también dígitos y subrayado. Nosotros los ugly-Americanos a veces queremos escribirlo como, por ejemplo,

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

Pero una clase de carácter doble negativa puede respetar la locale:

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

Eso es un poco opaco, por lo que una clase de carácter POSIX puede ser mejor para expresar la intención

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

O como szbalint sugirió

if (/^\p{Letter}+$/) { ... }
 276
Author: Greg Bacon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:59

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

/[^\S\r\n]/

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

 38
Author: Rory O'Kane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:47

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

[[:blank:]]

En Java (no olvide habilitar UNICODE_CHARACTER_CLASS):

\p{Blank}

En comparación con los similares \h, POSIX blankes compatible con algunos motores regex más ( referencia). Un beneficio importante es que su definición se fija en Anexo C: Propiedades de compatibilidad de las 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 en cuáles), mientras que las clases de caracteres POSIX son a menudo por defecto ASCII-only (como en Java).

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

  • U + 180E VOCAL MONGOLA SEPARADOR
  • U + 200B ESPACIO DE ANCHO CERO
  • U + 200C ANCHO CERO SIN ENSAMBLADOR
  • U + 200D CARPINTERO DE ANCHO CERO
  • U + 2060 WORD JOINER
  • U + FEFF ESPACIO SIN RUPTURA DE ANCHO CERO

    Tomado de https://en.wikipedia.org/wiki/White-space_character

El mencionado separador de vocales mongol 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 que todos los demás espacios en blanco obedecen: puede 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 otra marca de orden de bytes) se ajusta a la regla de los espacios en blanco en mi libro. Por lo tanto, los incluyo en mi clase de caracteres de espacio en blanco horizontal.

En Java:

static public final String HORIZONTAL_WHITESPACE = "[\\p{Blank}\\u200B\\u2060\\uFFEF]"
 10
Author: Aleksandr Dubinsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-03 19:22:59

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

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

DEMO

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

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

DEMO

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

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

DEMO

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

DEMO

 8
Author: Avinash Raj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-08 00:31:43

m/ /g simplemente da espacio en / /, y funcionará. O use \S: reemplazará todos los caracteres especiales como tabulación, líneas nuevas, espacios, etc.

 -4
Author: saiprathapreddy.obula,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-13 01:47:28