varios utiliza sólo start siguientes regulares que patrones palabra mostrará líneas los las hacer expresiones exacta egrep doble cómo cuál con comienzan comandos comando buscar encoding grep matching diacritics iconv

encoding - utiliza - hacer doble grep



¿Cómo hacer un grep insensible a los acentos? (3)

No creo que esto se pueda hacer en grep, a menos que esté dispuesto a escribir un script de shell que use iconv y diff , que sería un poco visualmente diferente de lo que está solicitando.

Aquí hay algo muy cercano a su solicitud a través de un script rápido de Perl:

#!/usr/bin/perl # tgrep 0.1 Copyright 2014 by Adam Katz, GPL version 2 or later use strict; use warnings; use open qw(:std :utf8); use Text::Unidecode; my $regex = shift or die "Missing pattern./nUsage: tgrep PATTERN [FILE...]"; my $retval = 1; # default to false (no hits) while(<>) { my $line = "", my $hit = 0; while(//G(/S*(?:/s+|$))/g){ # for each word (w/ trailing spaces) my $word = $1; if(unidecode($word) =~ qr/$regex/) { # if there was a match $hit++; # note that fact $retval = 0; # final exit code will be 0 (true) $line .= "/e[1;31m$word/e[0;0m"; # display word in RED } else { $line .= $word; # display non-matching word normally } } print $line if $hit; # only display lines with matches } exit $retval;

Markdown no me permite hacer texto en rojo, así que aquí está el resultado con los hits entre comillas:

$ echo "match àei but also äēì and possibly æi" | tgrep aei match "àei" but also "äēì" and possibly "æi"

Esto resaltará las palabras coincidentes en lugar de la coincidencia real, lo que sería muy difícil de hacer sin crear clases de caracteres masivos y / o componer un analizador de expresiones regulares por partes. Por lo tanto, buscar el patrón "ae" en lugar de "aei" produciría los mismos resultados (en este caso).

Ninguno de los indicadores de grep se replica en este ejemplo de juguete. Yo quería mantenerlo simple.

¿Hay alguna forma de hacer una búsqueda insensible al acento con grep, preferiblemente manteniendo la opción --color? Con esto quiero decir grep --secret-accent-insensitive-option aei coincidiría con aei pero también con äēì y posiblemente con æi.

Sé que puedo usar iconv -t ASCII//TRANSLIT para eliminar acentos de un texto, pero no veo cómo puedo usarlo para que coincida, ya que el texto se transforma (podría funcionar para grep -c o -l)


Realmente más rápido que la solución perl para mí que usa grep de php (se puede adaptar).

Strtolower su cadena de consulta sin acentos, luego reemplace algunas letras con sus formas de acento, y grep -i para las investigaciones de casos insensibles (tenga cuidado con las cotizaciones en $ q):

// Your query string $q = ''Maxime Bernié''; $accents = array( ''a'' => ''[aáàâäãå]'', ''e'' => ''[eéèêë]'', ''i'' => ''[iíìîï]'', ''o'' => ''[oóòôöõ]'', ''u'' => ''[uúùûü]'', ''c'' => ''[cç]'', ''n'' => ''[nñ]'', ''y'' => ''[ýÿ]'' ); $q = remove_accents(strtolower($q)); $qa = str_split($q); foreach ($qa as $k => $v) { if (isset($accents[$v])) { $qa[$k] = $accents[$v]; } } $q = implode('''', $qa); echo system(''cat file.txt | grep -i "''.$q.''"''); function remove_accents($str, $charset=''utf-8'') { $str = htmlentities($str, ENT_NOQUOTES, $charset); $str = preg_replace(''#&([A-za-z])(?:acute|cedil|caron|circ|grave|orn|ring|slash|th|tilde|uml);#'', ''/1'', $str); $str = preg_replace(''#&([A-za-z]{2})(?:lig);#'', ''/1'', $str); $str = preg_replace(''#&[^;]+;#'', '''', $str); return $str; }


(Disculpas por la publicación doble, pero esta es definitivamente una respuesta distinta. Esta también es la respuesta correcta . Solo me enteré hace unos minutos).

Usted está buscando una gran cantidad de clases de equivalencia de expresiones regulares POSIX:

14.3.6.2 Operadores de clase de equivalencia ( [= … =] )

    Regex reconoce las expresiones de clase de equivalencia dentro de las listas. Una expresión de clase de equivalencia es un conjunto de elementos de clasificación que pertenecen a la misma clase de equivalencia. Se forma una expresión de clase de equivalencia colocando un elemento de clasificación entre un operador de clase de equivalencia abierta y un operador de clase de equivalencia cerrada . [= representa el operador open-equivalence-class y =] representa el operador close-equivalence-class. Por ejemplo, si a y A fueran una clase de equivalencia, entonces tanto [[=a=]] como [[=A=]] coincidirían con a y con A Si el elemento de clasificación en una expresión de clase de equivalencia no es parte de una clase de equivalencia, entonces el emparejador considera que la expresión de clase de equivalencia es un símbolo de clasificación.

Estoy usando carpos en la línea siguiente para indicar qué es realmente coloreado. También pellizqué la cadena de prueba para ilustrar un punto sobre el caso.

$ echo "I match àei but also äēì and possibly æi" | grep ''[[=a=]][[=e=]][[=i=]]'' I match àei but also äēì and possibly æi ^^^ ^^^

Esto coincide con todas las palabras como aei . El hecho de que no concuerde con æi debe ser un recordatorio de que estás comprometido con el mapeo que existe en la biblioteca de expresiones regulares que estás utilizando (presumiblemente gnulib, que es lo que he vinculado y citado), aunque creo que es bastante probable que los dígrafos están más allá del alcance incluso del mejor mapa de clase de equivalencia.

No debe esperar que las clases de equivalencia sean portátiles ya que son demasiado arcanas.

Llevando esto un paso más allá, si solo desea caracteres acentuados, las cosas se vuelven mucho más complicadas. Aquí cambié tu solicitud de aei a [aei] .

$ echo "I match àei but also äēì and possibly æi" | grep ''[[=a=][=e=][=i=]]'' I match àei but also äēì and possibly æi ^ ^ ^^^ ^ ^^^ ^ ^ ^

Limpiar esto para evitar coincidencias sin acentos requeriría tanto clases de equivalencia como look-ahead / look-behind, y aunque BRE (basic reexx POSIX) y ERE (regex POSIX extendido) son compatibles con el primero, ambos carecen del último. Libpcre (la biblioteca de C para expresiones regulares compatibles con perl que grep -P y la mayoría usa) y perl admite lo último pero carecen de lo anterior:

Prueba # 1: grep con libpcre: falla

$ echo "I match àei but also äēì and possibly æi" / | grep -P ''[[=a=][=e=][=i=]](?<![aei])'' grep: POSIX collating elements are not supported

Prueba # 2: perl mismo: falla

$ echo "I match àei but also äēì and possibly æi" / | perl -ne ''print if /[[=a=][=e=][=i=]](?<![aei])/'' POSIX syntax [= =] is reserved for future extensions in regex; marked by <-- HERE in m/[[=a=][=e= <-- HERE ][=i=]](?<![aei])/ at -e line 1.

Pruebe # 3: python (que tiene su propia implementación PCRE): falla (silenciosa)

$ echo "I match àei but also äēì and possibly æi" / | python -c ''import re, sys; print re.findall(r"[[=a=][=e=][=i=]]", sys.stdin.read())'' []

¡Vaya, una característica de expresiones regulares que PCRE, python e incluso perl no admiten! No hay muchos de esos. (No importa que la queja esté en la segunda clase de equivalencia, todavía se queja dado solo /[[=a=]]/ .) Esto como evidencia adicional de que las clases de equivalencia son arcanas.

De hecho, parece que no hay bibliotecas PCRE capaces de clases de equivalencia; la sección sobre clases de equivalencia en regular-expressions.info afirma que solo las bibliotecas de expresiones regulares que implementan el estándar POSIX en realidad tienen este soporte. GNU grep acerca más, ya que puede hacer BRE, ERE y PCRE, pero no puede combinarlos.

Entonces lo haremos en dos partes.

Prueba el n. ° 4: trucos desagradables: éxito

$ echo "I match àei but also äēì and possibly æi" / | grep --color=always ''[[=a=][=e=][=i=]]'' / | perl -pne "s//e/[${GREP_COLOR:-01;31}m/e/[K(?i)([aei])//$1/g" I match àei but also äēì and possibly æi ^ ^^^

Caminata del código:

  • grep fuerza el color para que perl pueda perl los códigos de color para observar las coincidencias
  • ${GREP_COLOR:-01;31} toma nota del color de grep (con el mismo color rojo brillante predeterminado)
  • s/// comando s/// perl coincide con el código de color completo y luego con las letras sin acentos que queremos eliminar de los resultados finales. Reemplaza todo eso con las letras (sin color)
  • Cualquier cosa después de (?i) en el perl regex es insensible a mayúsculas ya que [[=i=]] coincide con I
  • perl -p imprime cada línea de su entrada una vez completada su ejecución -e

Para obtener más información sobre BRE vs ERE frente a PCRE y otros, consulte esta publicación regular de StackExchange o las expresiones regulares de POSIX en regular-expressions.info . Para obtener más información sobre las diferencias por idioma (incluyendo libpcre vs python PCRE vs perl), busque herramientas en regular-expressions.info .