Necesito una expresión regular capaz de coincidir con todo menos una cadena que comience con un patrón específico (específicamente index.phpy lo que sigue, como index.php?id=2342343)
@ThomasOwens: Depende. Depende de qué parte de la expresión se negará. Si se va a negar toda la expresión, entonces tienes un punto. Por ejemplo, si desea codificar "si la cadena no contiene 'Bruce' como una subcadena, entonces haga algo", usaría simplemente / Bruce /, y colocaría la negación en la declaración if, fuera de la expresión regular . Pero podría ser que le gustaría negar alguna subexpresión. Digamos que estás buscando algo como nombre, apellido, donde el nombre es Bruce, y el apellido lo es todo excepto XYZ, donde XYZ es el apellido de alguna celebridad llamada Bruce.
mathheadinclouds
Respuestas:
250
No es un experto en expresiones regulares, pero creo que podría usar una búsqueda negativa desde el principio, por ejemplo ^(?!foo).*$, no debería coincidir con nada que comience desde el principio foo.
Otros motores que permiten búsquedas: (cat)|[^c]*(?:c(?!at)[^c]*)*(o (?s)(cat)|(?:(?!cat).)*, o (cat)|[^c]+(?:c(?!at)[^c]*)*|(?:c(?!at)[^c]*)+[^c]*) y luego verificar con el idioma significa: si el Grupo 1 coincide, no es lo que necesitamos, de lo contrario, tome el valor de coincidencia si no está vacío
un cierto carácter único o un conjunto de caracteres :
Nota de demostración : la nueva línea \nse usa dentro de las clases de caracteres negadas en las demostraciones para evitar el desbordamiento de coincidencias a las líneas vecinas. No son necesarios al probar cadenas individuales.
Nota de anclaje : en muchos idiomas, use \Apara definir el inicio inequívoco de la cadena y \z(en Python \Z, en JavaScript, $está bien) definir el final de la cadena.
Nota de puntos : en muchos sabores (pero no en POSIX, TRE, TCL), .coincide con cualquier carácter excepto un carácter de nueva línea . Asegúrese de utilizar el modificador DOTALL correspondiente ( /sen PCRE / Boost / .NET / Python / Java y /men Ruby) para .que coincida con cualquier carácter, incluida una nueva línea.
Nota de barra invertida : en los lenguajes donde tiene que declarar patrones con cadenas C que permiten secuencias de escape (como \npara una nueva línea), debe duplicar las barras invertidas que escapan caracteres especiales para que el motor pueda tratarlos como caracteres literales (por ejemplo, en Java, world\.será declarado como "world\\.", o use una clase de caracteres:) "world[.]". Utilice literales de cadena sin formato (Python r'\bworld\b'), literales de cadena textuales de C # @"world\."o anotaciones literales de cadena / regex /world\./.
Genial escribir! Para el caso de "una cadena (no) igual a alguna cadena", con el ejemplo de ^(?!foo$), ¿por qué el signo de dólar debe estar entre paréntesis para que la expresión funcione? Esperaba ^(?!foo)$dar los mismos resultados, pero no es así.
Grant Humphries
3
@GrantHumphries: cuando el $ancla está dentro de la búsqueda anticipada, es parte de la condición, parte de esa afirmación de ancho cero . Si estuviera afuera, como adentro ^(?!foo)$, será parte del patrón de consumo que requiere el final de la cadena justo después del inicio de la cadena, lo que hace que la búsqueda anticipada negativa sea irrelevante ya que siempre devolverá verdadero (no puede haber ningún texto después del final de la cadena) , mucho menos foo). Entonces, ^(?!foo$)coincide con el inicio de una cadena que no se sigue con la fooque se sigue con el final de la cadena. ^(?!foo)$coincide con una cadena vacía.
Wiktor Stribiżew
@ robots.txt Por favor, elimine estos comentarios. Estás haciendo una pregunta XY. Las clases de personajes están destinadas a unir caracteres individuales, no hay forma de definir una secuencia de caracteres con ellos. Probablemente debería encontrar la subcadena entre el inicio de una cadena y la primera aparición de coto lan, y eliminar la coincidencia, como regex.replace(myString, "^.*?(?:cot|lan)\s*", "").
Eso es cierto, pero solo procesa un personaje a la vez. Si desea excluir una secuencia de dos o más caracteres, debe usar la búsqueda anticipada negativa como dijeron los otros respondedores.
Alan Moore
solución perfecta para eliminar cualquier carácter no deseado, excepto aquellos en el patrón. gracias
Sirmyself
@Alan, "... tienes que usar una mirada negativa hacia adelante ..." es incorrecto, pero no deberíamos ser demasiado duros contigo porque Wiktor no publicó su respuesta, lo que muestra por qué, hasta 2016.
Cary Swoveland
6
Simplemente coincida y /^index\.php/luego rechace lo que coincida.
Necesito un poder expresión regular para que coincida con todo , pero excepto una cadena que comienza conindex.php un patrón específico (en concreto index.php y lo que sigue, como index.php? Id = 2342343)
El OP solicitó específicamente una expresión regular ... ¡No estoy seguro de que esto ayude! (Puede estar usando grepen la línea de comandos, por ejemplo, o Perl / Python / cualquier otro idioma, o un comando "Ejecutar esta expresión regular para cada línea" en un editor de texto, etc.)
Respuestas:
No es un experto en expresiones regulares, pero creo que podría usar una búsqueda negativa desde el principio, por ejemplo
^(?!foo).*$
, no debería coincidir con nada que comience desde el principiofoo
.fuente
^((?!foo).)*$
( stackoverflow.com/a/406408/3964381 )Regex: coincide con todo menos :
foo
):^(?!foo).*$
^(?!foo)
^(([^f].{2}|.[^o].|.{2}[^o]).*|.{0,2})$
^([^f].{2}|.[^o].|.{2}[^o])|^.{0,2}$
world.
al final):(?<!world\.)$
^.*(?<!world\.)$
^(.*([^w].{5}|.[^o].{4}|.{2}[^r].{3}|.{3}[^l].{2}|.{4}[^d].|.{5}[^.])|.{0,5})$
([^w].{5}|.[^o].{4}|.{2}[^r].{3}|.{3}[^l].{2}|.{4}[^d].|.{5}[^.]$|^.{0,5})$
foo
) (sin patern compatible con POSIX, lo siento):^(?!.*foo)
^(?!.*foo).*$
|
símbolo)^[^|]*$
foo
):^(?!foo$)
^(?!foo$).*$
^(.{0,2}|.{4,}|[^f]..|.[^o].|..[^o])$
cat
):/cat(*SKIP)(*FAIL)|[^c]*(?:c(?!at)[^c]*)*/i
o/cat(*SKIP)(*FAIL)|(?:(?!cat).)+/is
(cat)|[^c]*(?:c(?!at)[^c]*)*
(o(?s)(cat)|(?:(?!cat).)*
, o(cat)|[^c]+(?:c(?!at)[^c]*)*|(?:c(?!at)[^c]*)+[^c]*
) y luego verificar con el idioma significa: si el Grupo 1 coincide, no es lo que necesitamos, de lo contrario, tome el valor de coincidencia si no está vacío[^a-z]+
(cualquier carácter que no sea una letra ASCII en minúsculas)|
:[^|]+
Nota de demostración : la nueva línea
\n
se usa dentro de las clases de caracteres negadas en las demostraciones para evitar el desbordamiento de coincidencias a las líneas vecinas. No son necesarios al probar cadenas individuales.Nota de anclaje : en muchos idiomas, use
\A
para definir el inicio inequívoco de la cadena y\z
(en Python\Z
, en JavaScript,$
está bien) definir el final de la cadena.Nota de puntos : en muchos sabores (pero no en POSIX, TRE, TCL),
.
coincide con cualquier carácter excepto un carácter de nueva línea . Asegúrese de utilizar el modificador DOTALL correspondiente (/s
en PCRE / Boost / .NET / Python / Java y/m
en Ruby) para.
que coincida con cualquier carácter, incluida una nueva línea.Nota de barra invertida : en los lenguajes donde tiene que declarar patrones con cadenas C que permiten secuencias de escape (como
\n
para una nueva línea), debe duplicar las barras invertidas que escapan caracteres especiales para que el motor pueda tratarlos como caracteres literales (por ejemplo, en Java,world\.
será declarado como"world\\."
, o use una clase de caracteres:)"world[.]"
. Utilice literales de cadena sin formato (Pythonr'\bworld\b'
), literales de cadena textuales de C #@"world\."
o anotaciones literales de cadena / regex/world\./
.fuente
^(?!foo$)
, ¿por qué el signo de dólar debe estar entre paréntesis para que la expresión funcione? Esperaba^(?!foo)$
dar los mismos resultados, pero no es así.$
ancla está dentro de la búsqueda anticipada, es parte de la condición, parte de esa afirmación de ancho cero . Si estuviera afuera, como adentro^(?!foo)$
, será parte del patrón de consumo que requiere el final de la cadena justo después del inicio de la cadena, lo que hace que la búsqueda anticipada negativa sea irrelevante ya que siempre devolverá verdadero (no puede haber ningún texto después del final de la cadena) , mucho menosfoo
). Entonces,^(?!foo$)
coincide con el inicio de una cadena que no se sigue con lafoo
que se sigue con el final de la cadena.^(?!foo)$
coincide con una cadena vacía.cot
olan
, y eliminar la coincidencia, comoregex.replace(myString, "^.*?(?:cot|lan)\s*", "")
.Puede poner un
^
al comienzo de un conjunto de caracteres para que coincida con cualquier cosa que no sean esos caracteres.coincidirá con todo menos
=
fuente
Simplemente coincida y
/^index\.php/
luego rechace lo que coincida.fuente
str !~ /\Aindex\.php/
.En python:
fuente
Utilice el método Exec
U otro partido
fuente
¿Qué tal no usar regex:
fuente
grep
en la línea de comandos, por ejemplo, o Perl / Python / cualquier otro idioma, o un comando "Ejecutar esta expresión regular para cada línea" en un editor de texto, etc.)