2011-01-04 23 views
14

Estoy tratando de armar una expresión regular para un comando de JavaScript que cuente con precisión el número de palabras en un área de texto.Expresión regular para contar palabras con precisión usando JavaScript

Una solución que había encontrado es el siguiente:

document.querySelector("#wordcount").innerHTML = document.querySelector("#editor").value.split(/\b\w+\b/).length -1; 

Pero esto no cuenta los caracteres no latinos (por ejemplo: cirílico, Hangul, etc); se salta completamente sobre ellos.

Otro junté:

document.querySelector("#wordcount").innerHTML = document.querySelector("#editor").value.split(/\s+/g).length -1; 

Pero esto no cuenta con precisión a menos que el documento termina en un carácter de espacio. Si se agrega un carácter de espacio al valor que se cuenta, cuenta 1 palabra incluso con un documento vacío. Además, si el documento comienza con un carácter de espacio, se contará una palabra extraña.

¿Hay una expresión regular que pueda poner en este comando que cuente las palabras con precisión, independientemente del método de entrada?

+3

Fuera de tema, pero 'document.querySelector (" # wordcount ")' se puede escribir 'document.getElementById (" wordcount ")', que puede ser más compatible entre navegadores o más rápido; es poco probable que sea menos compatible o más lento. –

+3

Falta una definición precisa del término "palabra". – Tomalak

+4

@Tomalak, falta en general, o falta en la pregunta? ;) –

Respuesta

35

Esto debería hacer lo que está buscando:

value.match(/\S+/g).length; 

En lugar de la división de la cadena,' volver a coincidir en cualquier secuencia de caracteres que no sean espacios en blanco.

está la ventaja añadida de ser fácilmente capaz de extraer cada palabra si es necesario;)

+9

'[^ \ s] +' == 'S +' ;-) – Tomalak

+0

Gracias @Tomalak :) Actualizado. –

+0

Gracias. Una pregunta sin embargo. El uso de la coincidencia en lugar de la división devuelve nulo cuando no hay palabras, incluso si hay caracteres de espacio. Puedo usar un comando if/else para resolver esto, pero ¿hay una mejor manera? –

7

tratar de contar nada que no sea un espacio en blanco y con un límite de palabra:

value.split(/\b\S+\b/g).length 

también se podría tratar de usar rangos de Unicode, pero no estoy seguro de si la siguiente es completa:

value.split(/[\u0080-\uFFFF\w]+/g).length 
+3

'value.split' es el camino equivocado, pero si en su lugar se hace' (value.match (/ \ b \ S + \ b/g) || []). Length', esto funciona bastante bien.Encontré los ejemplos de Phrogz en la respuesta aceptada una prueba útil; esto da: 'count (" you-and-I ") == 1',' count ("you & I") == 2', 'count (" tú - y yo ") == 3',' count ("Ejemplos de Phrogz") == 2'. El único cuestionable es "tú-y-yo", pero esta construcción es lo suficientemente rara como para que la complejidad adicional probablemente no valga la pena, especialmente para asegurarte de que tienes posesivos correctos. –

1

se podría extender/cambio que métodos como éste

document.querySelector("#wordcount").innerHTML = document.querySelector("#editor").value.split(/\b\(.*?)\b/).length -1; si desea hacer coincidir cosas como direcciones e-mail, así

y

document.querySelector("#wordcount").innerHTML = document.querySelector("#editor").value.trim().split(/\s+/g).length -1;

también tratar de usar \s como su la \w para Unicode

fuente: http: //www.regular-expressions.info/charclass.html

2

La expresión regular correcta sería /s+/ con el fin de descartar los no palabras:

'Lorem ipsum dolor , sit amet'.split(/\S+/g).length 
7 
'Lorem ipsum dolor , sit amet'.split(/\s+/g).length 
6 
+2

¿De verdad crees que una coma debería contarse como una palabra? – Phrogz

+0

'',,,,' 'tiene 5 palabras según su solución: D – Emadpres

-2

Si JavaScript entiende clase puntuacion [[:punct:]] y una afirmación de búsqueda hacia delante (?=)
entonces esto debe conseguir todas las palabras:

/[\s[:punct:]]*(\w(?:\w|[[:punct:]](?=[\w[:punct:]]))*)/ 

o, si no tiene el constructo (? :) ...

/[\s[:punct:]]*(\w(\w|[[:punct:]](?=[\w[:punct:]]))*)/ 

El uso de este en Perl sería algo así:

# Extracting and count the number of words 
# 
use strict; 
use warnings; 

my $text = q(
    I confirm that sufficient information and detail have been 
    reported in this technical report, that it's "scientifically" sound, 
    and that appropriate conclusion's have been included 
); 

my $regex = qr/ [\s[:punct:]]* (\w (?: \w | [[:punct:]](?=[\w[:punct:]]))*) /x; 
my $wordcount = 0; 

while ($text =~ /$regex/g) 
{ 
    print "$1\n"; 
    $wordcount++; 
} 

print "\n", '-'x20, "\nFound $wordcount words\n\n"; 

Salida:

I 
confirm 
that 
sufficient 
information 
and 
detail 
have 
been 
reported 
in 
this 
technical 
report 
that 
it's 
scientifically 
sound 
and 
that 
appropriate 
conclusion's 
have 
been 
included 

-------------------- 
Found 25 words 
0

mi sencilla biblioteca JavaScript, llamados FuncJS tiene una función llamada "count()" que hace exactamente lo que se llama - contar palabras.

Por ejemplo, digamos que usted tiene una cadena llena de palabras, sólo tiene que colocarlo entre los soportes de función, así:

count("How many words are in this string?"); 

y luego llamar a la función, que a su vez devolverá el número de palabras. Además, esta función está diseñada para ignorar cualquier cantidad de espacio en blanco, dando así un resultado preciso.

Para obtener más información sobre esta función, lea la documentación en http://docs.funcjs.webege.com/count().html y el enlace de descarga de FuncJS también se encuentra en la página.

Espero que esto ayude a cualquiera que quiera hacer esto! :)

1

Trate

value.match(/\w+/g).length; 

Esto coincidirá con una cadena de caracteres que pueden estar en una palabra. Mientras que algo como:

value.match(/\S+/g).length; 

dará lugar a un recuento incorrecto si el usuario agrega comas u otros puntuacion que no vaya seguida de un espacio - o agrega una coma con un espacio de cada lado de ella.

2

Para mí esto dio los mejores resultados:

value.split(/\b\W+\b/).length 

con

var words = value.split(/\b\W+\b/) 

a obtener todas las palabras.

Explicación:

  • \ b es un límite de palabra
  • \ W es un personaje no-palabra, el capital por lo general significa la negación
  • '+' significa 1 o más caracteres o el carácter prefijado clase

Recomiendo aprender expresiones regulares. Es una gran habilidad porque son muy poderosos. ;-)

Cuestiones relacionadas