Por cierto, estos personajes son también "espacios en blanco": [\r\f].
Eugene Yarmash
2
@eugeney, ¿alguien sigue haciendo feeds de formularios? (\ f's)
Aran Mulholland
1
@AranMulholland: Cualquiera que tenga una impresora orientada a los personajes. La mayoría de las impresoras tienen un modo de caracteres, así como PostScript o como se llame la interfaz de Hewlett Packard, y para lanzar una página se envía un formulario.
Borodin
1
@Borodin Hewlett Packard se llama PCL (Lenguaje de control de la impresora).
CB_Ron
Respuestas:
182
Las versiones de Perl 5.10 y posteriores admiten clases de caracteres verticales y horizontales subsidiarias \vy \h, además, la clase de caracteres de espacio en blanco genérico\s
La solución más limpia es usar la clase de caracteres de espacio en blanco horizontal\h . Esto coincidirá con la pestaña y el espacio del conjunto ASCII, el espacio sin interrupción del 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 de espacio en blanco vertical que coinciden \vy dieciocho caracteres horizontales que coinciden \h. \scoincide con veintitrés personajes
Todos los caracteres de espacio en blanco son verticales u horizontales sin superposición, pero no son subconjuntos adecuados porque \htambién coinciden con U + 00A0 ESPACIO SIN INTERRUPCIONES, y \vtambién coinciden con U + 0085 LÍNEA SIGUIENTE, ninguno de los cuales coincide con\s
@AvinashRaj: Esta pregunta es sobre Perl, que ciertamente es compatible con PCRE
Borodin
2
@AvinashRaj: Excepto que [[:blank:]]no coincide con ninguna ruptura espacio-- o"\xA0"
Borodin
66
Quiero mencionar que \hfuncionó perfectamente para mi caso de uso, que estaba haciendo una búsqueda / reemplazo en Notepad ++ en 1 o más espacios contiguos de líneas no nuevas. Nada más (simple) funcionó.
squidbe
8
Lo que hace que Perl sea \hligeramente no estándar es su inclusión MONGOLIAN VOWEL SEPARATOR. Unicode no lo considera espacio en blanco. Por esa razón, Perl \hdifiere de POSIX blank( [[:blank:]]en Perl, \p{Blank}en Java) y Java 8 \h. Es cierto que es un caso extremo.
Aleksandr Dubinsky
362
Use un doble negativo:
/[^\S\r\n]/
Es decir, no espacio en blanco (la S mayúscula se complementa) o no retorno de carro o no nueva línea. Distribuyendo el exterior no ( es decir , el complemento ^en la clase de caracteres) con la ley de De Morgan , esto es equivalente a "espacio en blanco pero no retorno de carro o nueva línea". La inclusión de ambos \ry \nen el patrón maneja correctamente todas las convenciones de nueva línea de Unix (LF), Mac OS (CR) clásico y DOS-ish (CR LF) .
Antes de Perl v5.18, \sno coincidía con la pestaña vertical. [^\S\cK](oscuramente) coincide con lo que \stradicionalmente hacía.
La misma sección de perlrecharclass también sugiere otros enfoques que no ofenden la oposición de los profesores de idiomas a los negativos dobles.
Fuera de la configuración regional y las reglas Unicode o cuando el /acambio está en vigor, " \scoincide [\t\n\f\r ]y, comenzando en Perl v5.18, la pestaña vertical \cK". Deseche \ry \ndeje /[\t\f\cK ]/para espacios en blanco coincidentes pero no para nueva línea.
sub ws_not_nl {local($_)=<<'EOTable';0x0009 CHARACTER TABULATION h s
0x000a LINE FEED (LF) vs
0x000b LINE TABULATION vs [1]0x000c FORM FEED (FF) vs
0x000d CARRIAGE RETURN (CR) vs
0x0020 SPACE h s
0x0085 NEXT LINE (NEL) vs [2]0x00a0 NO-BREAK SPACE h s [2]0x1680 OGHAM SPACE MARK h s
0x2000 EN QUAD h s
0x2001 EM QUAD h s
0x2002 EN SPACE h s
0x2003 EM SPACE h s
0x2004 THREE-PER-EM SPACE h s
0x2005 FOUR-PER-EM SPACE h s
0x2006 SIX-PER-EM SPACE h s
0x2007 FIGURE SPACE h s
0x2008 PUNCTUATION SPACE h s
0x2009 THIN SPACE h s
0x200a HAIR SPACE h s
0x2028 LINE SEPARATOR vs
0x2029 PARAGRAPH SEPARATOR vs
0x202f NARROW NO-BREAK SPACE h s
0x205f MEDIUM MATHEMATICAL SPACE h s
0x3000 IDEOGRAPHIC SPACE h s
EOTablemy $class;while(/^0x([0-9a-f]{4})\s+([A-Z\s]+)/mg){my($hex,$name)=($1,$2);nextif $name =~/\b(?:CR|NL|NEL|SEPARATOR)\b/;
$class .="\\N{U+$hex}";}
qr/[$class]/u;}
Otras aplicaciones
El truco doble negativo también es útil para hacer coincidir los caracteres alfabéticos. Recuerde que \wcoincide con "caracteres de palabras", caracteres alfabéticos y dígitos y guiones bajos. Los estadounidenses feos a veces queremos escribirlo como, digamos,
if(/[A-Za-z]+/){...}
pero una clase de caracteres doble negativa puede respetar la configuración regional:
if(/[^\W\d_]+/){...}
Expresar "un carácter de palabra pero no un dígito o guión bajo" de esta manera es un poco opaco. Una clase de caracteres POSIX comunica la intención más directamente
Inteligente, pero el comportamiento es muy sorprendente, y no veo cómo es menos incómodo.
Qwertie
77
@Qwertie: ¿qué es sorprendente? ¿Menos incómodo que qué?
Ysth
9
Excelentemente horrible
9
Esto es muy bueno. Según lo solicitado, usted hace coincidir el espacio en blanco (no solo algunos caracteres de espacio en blanco) y excluye el carácter de avance de línea. Su solución no tiene que ver con la pregunta: "qué caracteres de espacios en blanco existen", como no debería. Esto es precisamente lo que estaba buscando. (Como se ha señalado por @Rory, una 'nueva línea' también puede incluir \r, por ejemplo, en Windows, por lo que considerar exluding los del partido, así: /[^\S\r\n]/)
Timo
1
Esto sin duda satisfará las necesidades del OP y de prácticamente todos los demás que buscan esta pregunta (de todos modos, hablantes de inglés). Pero sigue siendo una mala respuesta. Simplemente no hay excusa para usar esta solución cuando \hestá disponible.
Esta expresión regular es más segura que /[^\S\n]/con no \r. Mi razonamiento es que Windows usa \r\npara las nuevas líneas y Mac OS 9 \r. Es poco probable que lo encuentres \rsin \nhoy en día, pero si lo encuentras, no podría significar nada más que una nueva línea. Por lo tanto, dado que \rpuede significar una nueva línea, también debemos excluirla.
La solución de +1 Greg terminó corrompiendo mi texto, el tuyo funcionó bien.
Timo Huovinen
Es posible que se sorprenda de cuántos programas todavía usan "\ r" para los finales de línea. A veces me tomó un tiempo darme cuenta de que mi problema era que el archivo los usaba. O que usó la codificación de caracteres MacRoman ...
mivk
2
parece que @Greg primero lo hizo "incorrecto", lo cambió y no le dio crédito. Por eso estoy votando aquí.
Andre Elrico
14
La expresión regular a continuación coincidiría con espacios en blanco pero no con un nuevo carácter de línea.
No sé por qué no mencionaron la clase de caracteres POSIX [[:blank:]]que coincide con espacios en blanco horizontales ( espacios y tabulaciones ). Esta clase de caracteres POSIX funcionaría en BRE ( expresiones regulares básicas ), ERE ( expresión regular extendida ), PCRE ( expresión regular compatible con Perl ).
Lo que está buscando es la blankclase de caracteres POSIX . En Perl se hace referencia como:
[[:blank:]]
en Java (no olvide habilitar UNICODE_CHARACTER_CLASS):
\p{Blank}
En comparación con similares \h, POSIX blankes compatible con algunos motores regex más ( referencia ). Un beneficio importante es que su definición se fija en el 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, \hopta por incluir adicionalmente el MONGOLIAN VOWEL SEPARATOR.) Sin embargo, un argumento a favor \hes que siempre detecta los caracteres Unicode (incluso si los motores no están de acuerdo en cuál), mientras que las clases de caracteres POSIX a menudo son ASCII por defecto -solo (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:
El mencionado separador de vocales de Mongolia no está incluido por lo que probablemente sea una buena razón. Esto, junto con 200C y 200D, se produce 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 ella. Son más como modificadores. Sin embargo, ZERO WIDTH SPACE, WORD JOINER, y ZERO WIDTH NON-BREAKING SPACE(si se utiliza como distinto de una marca de orden de bytes) ajustarse 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]"
Debe agregar los indicadores de compilación regexp apropiados a la compilación de Java y ejecutar Java 7 o posterior. En cualquier caso, la pregunta no era sobre Java o PCRE, por lo que todo esto es irrelevante.
tchrist
@tchrist Gracias por señalar esto. Actualizaré mi respuesta. Sin embargo, no estoy de acuerdo con que mi respuesta sea irrelevante. Lo que no tiene importancia es la perletiqueta en la pregunta original.
Aleksandr Dubinsky
1
@AleksandrDubinsky, \ p {Blank} no es compatible con JavaScript, por lo que definitivamente no es "estándar para todos los sabores de expresiones regulares" -1
Valentin Vasilyev
Más informativo Me resulta inquietante saber que no existe una clase general y completa de caracteres abreviados de "espacio en blanco horizontal", y que [\p{Blank}\u200b\u180e]se requieren horrores como . Es cierto que tiene sentido que un separador de vocales no se considere un espacio en blanco, pero por qué el espacio de ancho cero no está en clases como \sy \p{Blank}, me gana.
Timo
Seguimiento: leí que ambos se consideran 'límites neutrales', aunque eso no explica por qué .
Timo
-4
m/ /gsolo dale espacio / /y funcionará. O use \S: reemplazará todos los caracteres especiales como tabulación, líneas nuevas, espacios, etc.
[\r\f]
.Respuestas:
Las versiones de Perl 5.10 y posteriores admiten clases de caracteres verticales y horizontales subsidiarias
\v
y\h
, además, la clase de caracteres de espacio en blanco genérico\s
La solución más limpia es usar la clase de caracteres de espacio en blanco horizontal
\h
. Esto coincidirá con la pestaña y el espacio del conjunto ASCII, el espacio sin interrupción del ASCII extendido o cualquiera de estos caracteres UnicodeEl patrón de espacio vertical
\v
es menos útil, pero coincide con estos caracteres.Hay siete caracteres de espacio en blanco vertical que coinciden
\v
y dieciocho caracteres horizontales que coinciden\h
.\s
coincide con veintitrés personajesTodos los caracteres de espacio en blanco son verticales u horizontales sin superposición, pero no son subconjuntos adecuados porque
\h
también coinciden con U + 00A0 ESPACIO SIN INTERRUPCIONES, y\v
también coinciden con U + 0085 LÍNEA SIGUIENTE, ninguno de los cuales coincide con\s
fuente
\h
funciona solo en los idiomas que admitePCRE
.[[:blank:]]
no coincide con ninguna ruptura espacio--
o"\xA0"
\h
funcionó perfectamente para mi caso de uso, que estaba haciendo una búsqueda / reemplazo en Notepad ++ en 1 o más espacios contiguos de líneas no nuevas. Nada más (simple) funcionó.\h
ligeramente no estándar es su inclusiónMONGOLIAN VOWEL SEPARATOR
. Unicode no lo considera espacio en blanco. Por esa razón, Perl\h
difiere de POSIXblank
([[:blank:]]
en Perl,\p{Blank}
en Java) y Java 8\h
. Es cierto que es un caso extremo.Use un doble negativo:
Es decir, no espacio en blanco (la S mayúscula se complementa) o no retorno de carro o no nueva línea. Distribuyendo el exterior no ( es decir , el complemento
^
en la clase de caracteres) con la ley de De Morgan , esto es equivalente a "espacio en blanco pero no retorno de carro o nueva línea". La inclusión de ambos\r
y\n
en el patrón maneja correctamente todas las convenciones de nueva línea de Unix (LF), Mac OS (CR) clásico y DOS-ish (CR LF) .No es necesario tomar mi palabra:
Salida:
Tenga en cuenta la exclusión de la pestaña vertical, pero esto se aborda en v5.18 .
Antes de objetar con demasiada dureza, la documentación de Perl usa la misma técnica. Una nota al pie en la sección "Espacio en blanco" de perlrecharclass lee
La misma sección de perlrecharclass también sugiere otros enfoques que no ofenden la oposición de los profesores de idiomas a los negativos dobles.
Fuera de la configuración regional y las reglas Unicode o cuando el
/a
cambio está en vigor, "\s
coincide[\t\n\f\r ]
y, comenzando en Perl v5.18, la pestaña vertical\cK
". Deseche\r
y\n
deje/[\t\f\cK ]/
para espacios en blanco coincidentes pero no para nueva línea.Si su texto es Unicode, use un código similar al siguiente para construir un patrón de la tabla en la sección de documentación mencionada anteriormente .
Otras aplicaciones
El truco doble negativo también es útil para hacer coincidir los caracteres alfabéticos. Recuerde que
\w
coincide con "caracteres de palabras", caracteres alfabéticos y dígitos y guiones bajos. Los estadounidenses feos a veces queremos escribirlo como, digamos,pero una clase de caracteres doble negativa puede respetar la configuración regional:
Expresar "un carácter de palabra pero no un dígito o guión bajo" de esta manera es un poco opaco. Una clase de caracteres POSIX comunica la intención más directamente
o con una propiedad Unicode como szbalint sugirió
fuente
\r
, por ejemplo, en Windows, por lo que considerar exluding los del partido, así:/[^\S\r\n]/
)\h
está disponible.Una variación de la respuesta de Greg que también incluye retornos de carro:
Esta expresión regular es más segura que
/[^\S\n]/
con no\r
. Mi razonamiento es que Windows usa\r\n
para las nuevas líneas y Mac OS 9\r
. Es poco probable que lo 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, también debemos excluirla.fuente
La expresión regular a continuación coincidiría con espacios en blanco pero no con un nuevo carácter de línea.
MANIFESTACIÓN
Si desea agregar el retorno de carro también, agregue
\r
con el|
operador dentro de la búsqueda anticipada negativa.MANIFESTACIÓN
Agregue
+
después del grupo sin captura para que coincida con uno o más espacios en blanco.MANIFESTACIÓN
No sé por qué no mencionaron la clase de caracteres POSIX
[[:blank:]]
que coincide con espacios en blanco horizontales ( espacios y tabulaciones ). Esta clase de caracteres POSIX funcionaría en BRE ( expresiones regulares básicas ), ERE ( expresión regular extendida ), PCRE ( expresión regular compatible con Perl ).MANIFESTACIÓN
fuente
Lo que está buscando es la
blank
clase de caracteres POSIX . En Perl se hace referencia como:en Java (no olvide habilitar
UNICODE_CHARACTER_CLASS
):En comparación con similares
\h
, POSIXblank
es compatible con algunos motores regex más ( referencia ). Un beneficio importante es que su definición se fija en el 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
opta por incluir adicionalmente elMONGOLIAN VOWEL SEPARATOR
.) Sin embargo, un argumento a favor\h
es que siempre detecta los caracteres Unicode (incluso si los motores no están de acuerdo en cuál), mientras que las clases de caracteres POSIX a menudo son ASCII por defecto -solo (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:
SEPARADOR DE VOCALES MONGOLIANAS U + 180E
U + 200B ESPACIO ANCHO CERO
ANCHO CERO U + 200C SIN UNIÓN
UNIDAD DE ANCHO CERO U + 200D
U + 2060 WORD JOINER
U + FEFF ANCHO CERO ESPACIO SIN INTERRUPCIONES
Tomado de https://en.wikipedia.org/wiki/White-space_character
El mencionado separador de vocales de Mongolia no está incluido por lo que probablemente sea una buena razón. Esto, junto con 200C y 200D, se produce 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 ella. Son más como modificadores. Sin embargo,
ZERO WIDTH SPACE
,WORD JOINER
, yZERO WIDTH NON-BREAKING SPACE
(si se utiliza como distinto de una marca de orden de bytes) ajustarse 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:
fuente
perl
etiqueta en la pregunta original.[\p{Blank}\u200b\u180e]
se requieren horrores como . Es cierto que tiene sentido que un separador de vocales no se considere un espacio en blanco, pero por qué el espacio de ancho cero no está en clases como\s
y\p{Blank}
, me gana.m/ /g
solo dale espacio/ /
y funcionará. O use\S
: reemplazará todos los caracteres especiales como tabulación, líneas nuevas, espacios, etc.fuente