2009-07-02 11 views
63

Quería escribir una expresión regular para contar el número de espacios/pestañas/nueva línea en un fragmento de texto. Así que, ingenuamente, escribió lo siguiente: -Contar el número de coincidencias de una expresión regular en Javascript

numSpaces : function(text) { 
    return text.match(/\s/).length; 
} 

Por algunas razones desconocidas siempre devuelve 1. ¿Cuál es el problema con la declaración anterior? ya que he resuelto el problema con lo siguiente: -

numSpaces : function(text) { 
    return (text.split(/\s/).length -1); 
} 

Respuesta

121

El problema con el código inicial es que se echa en falta la global identifier:

>>> 'hi there how are you'.match(/\s/g).length; 
4 

Sin la parte g de la expresión regular que lo hará único partido la primera ocurrencia y detenerse allí.

También tenga en cuenta que su expresión regular contará espacios sucesivos dos veces:

>>> 'hi there'.match(/\s/g).length; 
2 

Si eso no es deseable, se puede hacer esto:

>>> 'hi there'.match(/\s+/g).length; 
1 
+5

Esto funciona siempre y cuando tenga al menos un espacio en su entrada. De lo contrario, match() arroja nulo de forma molesta. – sfink

+3

sfink es correcto, definitivamente quiere comprobar si match() devolvió null: 'var result = text.match (/ \ s/g); resultado de devolución? result.length: 0; ' –

+36

También puede protegerse contra el nulo usando esta construcción:' (str.match (...) || []) .length' –

7

Como se mencionó en my earlier answer, puede utilizar RegExp.exec() a iterar sobre todas las coincidencias y contar cada ocurrencia; la ventaja está limitada solo a la memoria, porque en general es un 20% más lenta que con String.match().

var re = /\s/g, 
count = 0; 

while (re.exec(text) !== null) { 
    ++count; 
} 

return count; 
0

('my string' || []).match(/\s/g).length;

Cuestiones relacionadas