Las diferentes herramientas y versiones de las mismas admiten diferentes variantes de expresiones regulares. La documentación de cada uno le dirá qué respaldan.
Existen estándares para que uno pueda confiar en un conjunto mínimo de características que están disponibles en todas las aplicaciones conformes.
Por ejemplo, todas las implementaciones modernas sed
e grep
implementan expresiones regulares básicas según lo especificado por POSIX (al menos una versión u otra del estándar, pero ese estándar no ha evolucionado mucho en ese sentido en las últimas décadas).
En POSIX BRE y ERE, tienes la [:alnum:]
clase de personaje. Eso coincide con letras y dígitos en su configuración regional (tenga en cuenta que a menudo incluye mucho más que a a-zA-Z0-9
menos que la configuración regional sea C).
Asi que:
grep -x '[[:alnum:]_]\{1,\}'
coincide con uno o más alnums o _.
[\w]
POSIX requiere que coincida con la barra diagonal inversa o w
. Por lo que no encontrará una grep
o sed
aplicación que está disponible en (a no ser a través de las opciones no estándar).
\w
POSIX no especifica el comportamiento solo, por lo que las implementaciones pueden hacer lo que quieran. GNU grep
agregó eso hace mucho tiempo.
GNU grep
solía tener su propio motor regexp, sin embargo, ahora usa el de GNU libc (aunque incorpora su propia copia).
Está destinado a combinar alnums y guiones bajos en su entorno local. Sin embargo, actualmente tiene un error, ya que solo coincide con caracteres de un solo byte (por ejemplo, no é en una configuración regional UTF-8 a pesar de que es claramente una letra y aunque coincide con é en todas las configuraciones regionales donde é es una sola personaje).
También hay un \w
operador regexp en perl regexp y en PCRE. PCRE / perl no son expresiones regulares POSIX, son simplemente otra cosa.
Ahora, con la forma en que GNU grep -P
usa PCRE, tiene el mismo problema que sin él -P
. Sin embargo, se puede solucionar allí usando (*UCP)
(aunque eso también tiene efectos secundarios en entornos locales que no son UTF8).
GNU sed
también usa las expresiones regulares libc de GNU para sus propias expresiones regulares. Sin embargo, lo usa de tal manera que no tiene el mismo error que GNU grep
.
GNU sed
no es compatible con PCRE. Hay algunas pruebas en el código de que se ha intentado antes, pero ya no parece estar en la agenda.
Si quieres las expresiones regulares de Perl, solo perl
úsalas.
De lo contrario, diría que en lugar de tratar de confiar en una característica no estándar falsa de su implementación particular de sed
/ grep
, sería mejor seguir con el estándar y el uso [_[:alnum:]]
.
[_[:alnum:]]
es una buena solución que me permite extenderla como[\w/]
([_[:alnum:]/]
en ese caso).grep
.Tienes razón,
\w
es parte de PCRE, expresiones regulares compatibles con Perl. Sin embargo, no es parte de la expresión regular 'estándar'. http://www.regular-expressions.info/posix.htmlAlgunas versiones de
sed
pueden admitirlo, pero sugeriría que la forma más fácil es usarloperl
ensed
modo especificando la-p
bandera. (Junto con el-e
). (Más detalles enperlrun
)Pero
[]
en ese ejemplo, no necesitas evitarlo, eso es para grupos de cosas válidas.O en Windows:
Ver
perlre
para más cosas PCRE.Puede obtener perl aquí: http://www.activestate.com/activeperl/downloads
fuente
\w
y[\w]
en mi pregunta. Lo actualizaré con las salidas de cada comando para dejar en claro cuál funciona y cuál no. En particular,sed
entiende\w
, pero no[\w]
. Además, necesito[\w]
trabajar porque quiero usar,[\w/]
por ejemplo.perl
puede hacerlo :).\w
estaba en GNU grep (en los años 80) antes de estar en perl y en GNU emacs probablemente incluso antes de eso.Sospecho que
grep
y estoysed
decidiendo de manera diferente cuándo aplicar el[]
y cuándo expandir el\w
. En perl, regex\w
significa cualquier carácter de palabra, y[]
define un grupo para aplicar cualquiera de los caracteres dentro de una coincidencia. Si "expande"\w
antes del[]
, será una clase de caracteres de todas las palabras. Si, en cambio lo hace[]
primero que tendrá una clase de carácter con dos personajes\
yw
por lo que se correspondería con cualquier patrón que contiene uno o más de esos dos personajes.Entonces parece que
sed
es ver[]
y tratarlo como si contuviera los caracteres exactos para que coincidan en lugar de honrar la secuencia especial\w
comoperl
y logrep
hacen. Por supuesto,[]
son completamente innecesarios en este ejemplo, pero uno podría imaginar casos en los que sería importante, pero luego podría hacer que funcione con parens y ors.fuente
\
es un código de escape, y lo usarías para delimitadores de escape. Inherentemente, eso significa que tiene que tener una precedencia más alta que cualquier otra cosa. Creo que es más probable que no se implemente porque\w
no es parte de la especificación de expresión regularecho whe\\ere | sed -r 's/[\w]+/gone/g
dagonehegoneere
como si` and
estuviera haciendo coincidir cada una de las w` y haciendo la sustitución