2011-12-21 16 views
8

Hola, soy nuevo en la expresión regular y esta puede ser una pregunta muy fácil (con suerte).expresión regular de Javascript: hacer coincidir algo hasta algo (si existe)

Estoy tratando de utilizar una solución para la clase 3 de cadena

  • "45%", resultado esperado: "45"
  • "45", resultado esperado: "45"
  • " ", resultado esperado: ""

lo que estoy tratando (por no ser la cadena str):

str.match(/(.*)(?!%*)/i)[1] 

Esto en mi cabeza sonaría como "coincide con cualquier instancia de hasta hasta '%' si se encuentra, o simplemente coincide con cualquier cosa"

En la cabeza de Firebug parece sonar más como "solo coincide con cualquier cosa y completamente hacer caso omiso de la mirada negativa ". También para hacerlo perezoso - (.*)? - no parece ayudar.

Olvidemos por un momento que en esta situación específica solo estoy haciendo coincidir los números, por lo que un /\d*/ haría. Intento entender una regla general para poder aplicarla cada vez que sea necesario.

¿Alguien sería tan amable de ayudarme?

+1

El lookahead negativo: '(?!% *)' Dice: _ "afirma que cero o más signos de porcentaje no siguen" _ ¡Esta afirmación nunca puede ser cierta porque '% *' siempre es verdad! ('% *' no coincide con nada, lo que es siempre cierto en todas partes, incluso para una cadena vacía). – ridgerunner

Respuesta

21

¿Y el más simple

str.match(/[^%]*/i)[0] 

Lo que significa, partido de cero o más caracteres, que no es un %.


Editar: Si necesidad de analizar hasta </a>, entonces se podría analizar una secuencia de caracteres PF, seguido por </a>, a continuación, a continuación, descartar el </a>, lo que significa que puedes usar positivo visión hacia adelante en lugar de negativo.

str.match(/.*?(?=<\/a>|$)/i)[0] 

Esto significa: partido de cero o más caracteres con pereza, hasta llegar a una final de la cadena o </a>.

Tenga en cuenta que *? es un solo operador, (.*)? no es lo mismo que .*?.

(. Y don't parse HTML with a single regex, como de costumbre)

+0

En Expresiones regulares, particularmente en el sabor de JavaScript, el carácter '^' significa emparejar desde el comienzo de la cadena de referencia. https: //developer.mozilla.org/es/JavaScript/Guide/Regular_Expressions – austincheney

+0

@austincheney: Eso es cierto cuando '^' se usa como delimitador de texto, pero '^' tiene un significado diferente cuando se usa dentro de una clase de caracteres, es decir, niega la coincidencia ("nada pero estos caracteres ... "). – bobbymcr

+0

Gracias Kenny, eso funciona. Pero, ¿y si "%" fuera ""? Me gustaría excluir un patrón de más de un solo personaje. Y para hacerlo más claro, "" (o cualquier patrón) podría o no estar allí. – undefinederror

0

que acabo de escribir exactamente la forma en que lo dijiste:

str.match(/(^[^%]*$)|^([^%]*)%.*/i) 

Esto coincidirá con cualquier cadena sin un '%' o la primera parte de una cadena que contiene un%. Tienes que obtener el resultado del 1er o 2do grupo.

EDIT: Esto es exactamente lo que quiere debajo

str.match(/(?:^[^%]*$)|^(?:[^%]*)(?=%)/) 
  • El: elimina toda la agrupación
  • La = es una búsqueda hacia delante para ver si la cadena contiene%
  • y [^? %] coincide con cualquier carácter que no sea%

por lo que las lecturas de expresiones regulares coinciden con cualquier cadena que no contenga%, O (de lo contrario, coincida) todas de los personajes antes de la primera%

3

La forma más fácil con una cadena de búsqueda exacta es saltarse las expresiones regulares y sólo tiene que utilizar indexOf, por ejemplo:

// String to be searched 
var s = "Here is a <a>link</a>." 

// String to find 
var searchString = "</a>"; 

// Final match 
var matched = ""; 

var c = s.indexOf(searchString); 
if (c >= 0) 
{ 
    // Returns the portion not including the search string; 
    // in this example, "Here is a <a>link". If you want the 
    // search string included, add the length of the search 
    // string to c. 
    matched = s.substring(c); 
} 
+0

Gracias bobby, pero estaba buscando una solución RegEx. Lo que describiste es lo que normalmente haría, pero al hacerlo terminaría reiterando este pequeño vocabulario mío ... – undefinederror

0

para que coincida con el 45, el 45%, y cualquier número de cualquier uso de este longitud (182%, 18242, etc.)

str.match(/([0-9]+)([%]?)/)[1]; 

si es necesario para que coincida con la cadena vacía también incluyen como ^$, partido de la nota ("...") [1] no estará definido para la cadena vacía, por lo que deberá probar la coincidencia y luego verificar [0] o ver si [1] no está definido.

str.match(/([0-9]+)([%]?)|^$/) 

si tiene que coincidir exactamente dos dígitos usan {2,2} anclaje de la expresión entre el inicio y final de línea de caracteres: "^ (exp) $"

str.match(/^([0-9]{2,2})([%]?)$/)[1]; 
4

Creo que esto es lo que está buscando:

/(?:(?!%).)*/ 

La . coincide con cualquier carácter, pero solo después del lookahead negativo, (?!%), confirma que el carácter no es %. Tenga en cuenta que cuando el centinela es un solo personaje como %, puede utilizar una clase de caracteres negada en su lugar, por ejemplo:

/[^%]*/ 

Pero para un centinela multi-personaje como </a>, usted tiene que utilizar el enfoque de búsqueda hacia delante:

/(?:(?!</a>).)*/i 

Esto en realidad está diciendo "cero o más caracteres de uno en uno, pero si el siguiente carácter resulta ser el comienzo de la secuencia de </a> o </A>, detenga sin consumirlo".

+0

Esto es genial. Exactamente lo que estaba buscando. Gracias a ti y a Kenny ahora sé cómo hacer un paso a la vez para asegurarme de que mi último paso no caiga en un cierto patrón '/ ((?! patrón).) * /' Y cómo hacer una larga caminata hasta que el el siguiente carácter es el comienzo de mi patrón, o el final de una cadena '/.*?(?= patrón | $) /'. Creo que Kenny's es más de lo que esperaba encontrar, mientras que el tuyo es menos obvio y definitivamente brillante. No creo que lo hubiera pensado alguna vez. ¡Gracias! – undefinederror

Cuestiones relacionadas