|
Página 1 de 2
|
[SOLUCIONADO... Casi] RegExp Y Los «flags»
Autor |
Mensaje |
Grandamakulo
Analista Programador
Registrado: Enero 2016
Mensajes: 311
Edad: 55 Ubicación: En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
|
[SOLUCIONADO... Casi] RegExp Y Los «flags»
Hola, compañeros:
Veréis, quiero «contar cosas» dentro de textos —por ejemplo, número de palabras, número de espacios en blanco, etc.— y creo que la mejor solución son las RegExp. Pero para contar se necesita la flag «/g» y no sé cómo emplearla en gambas.
Por ejemplo, para contar todos los caracteres, la RegExp sería «/./g». Pero, no sé por qué, gambas pasa de mí. Pongo un ejemplo:
Este ejemplo cuenta los caracteres en bruto, bytes puros con «Len»; los caracteres de la cadena, con «String.Len» y los caracteres reales con «/./g». Por cierto, que podéis probar a ver la diferencia entre pasarle una propiedad .Text y una .RichTex, ésta última con sus etiquetas y tal.
Pero, lo dicho, «/g» no funciona. ¿Alguna ayuda? Seguro que es una chorrada.
—Sí, ya he buscado por el foro, he visto los ejemplos de RegExp de nuestro compañero Juan y alguno más —
Gracias de antemano.
PS.—He probado también RegExp.Anchored como segundo y tercer argumento de RegExp.
última edición por Grandamakulo el Sabado, 14 Septiembre 2019, 12:52; editado 3 veces
|
#1 Miercoles, 04 Septiembre 2019, 09:24 |
|
|
shordi
Analista Programador
Registrado: Septiembre 2009
Mensajes: 4982
Edad: 64 Ubicación: Albacete
|
Re: RegEx Y Los «flags»
Nunca he usado esa clase, lo siento. Sin embargo... ¿Qué problema tienes con len(cadena)?. Si string.len(cadena) te da la longitud utf8, len(cadena) te da la longitud "real" de la cadena, se supone...
=================== No podemos regresar
|
#2 Miercoles, 04 Septiembre 2019, 17:29 |
|
|
Grandamakulo
Analista Programador
Registrado: Enero 2016
Mensajes: 311
Edad: 55 Ubicación: En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
|
Re: RegEx Y Los «flags»
Nunca he usado esa clase, lo siento. Sin embargo... ¿Qué problema tienes con len(cadena)?. Si string.len(cadena) te da la longitud utf8, len(cadena) te da la longitud "real" de la cadena, se supone...
Hola, Shordi:
Como bien dices, Sring.Len te da la longitud en caracteres y Len en bytes. Pero yo estoy buscando unos resultados un poco más completos, aprovechándome de RegEx. Por ejemplo, para el primer capítulo del Quijote, String.Len = 10.354, Len = 10.601 y "/./g" = 10.347 —éste último da los caracteres escritos, excepto saltos de línea: así cuenta, por ejemplo, el piopío alias Twitter—.
Además, " /(\n)[^\n]/g" —7 en el ejemplo— da el número de párrafos o " /([A-Za-zÁÉÍÓÚáéíóúÜüñÑ0-9])[A-Za-zÁÉÍÓÚáéíóúÜüñÑ0-9]*/g" —1.882 en el ejemplo— el número de palabras en español.
Pero tras una investigación más exhaustiva, me he dado cuenta que:
1. Necesito la versión javascript y no la PCRE.
2. No existe la flag «g» en gambas.
Por tanto, desecho calcular estadísticas así.
PS.—Para contar palabras en varios alfabetos latinos como inglés, francés, español, alemán, esperanto, etc: /([A-Za-z\u00C0-\u02B0])[A-Za-z\u00C0-\u02B0]*/g
última edición por Grandamakulo el Jueves, 05 Septiembre 2019, 09:55; editado 2 veces
|
#3 Jueves, 05 Septiembre 2019, 09:47 |
|
|
gambafeliz
Analista Programador
Registrado: Julio 2019
Mensajes: 830
Edad: 54
|
Re: RegEx Y Los «flags»
Nunca he usado esa clase, lo siento. Sin embargo... ¿Qué problema tienes con len(cadena)?. Si string.len(cadena) te da la longitud utf8, len(cadena) te da la longitud "real" de la cadena, se supone...
Hola, Shordi:
Como bien dices, Sring.Len te da la longitud en caracteres y Len en bytes. Pero yo estoy buscando unos resultados un poco más completos, aprovechándome de RegEx. Por ejemplo, para el primer capítulo del Quijote, String.Len = 10.354, Len = 10.601 y "/./g" = 10.347 —éste último da los caracteres escritos, excepto saltos de línea: así cuenta, por ejemplo, el piopío alias Twitter—.
Además, " /(
)[^
]/g" —7 en el ejemplo— da el número de párrafos o " /([A-Za-zÁÉÍÓÚáéíóúÜüñÑ0-9])[A-Za-zÁÉÍÓÚáéíóúÜüñÑ0-9]*/g" —1.882 en el ejemplo— el número de palabras en español.
Pero tras una investigación más exhaustiva, me he dado cuenta que:
1. Necesito la versión javascript y no la PCRE.
2. No existe la flag «g» en gambas.
Por tanto, desecho calcular estadísticas así.
PS.—Para contar palabras en varios alfabetos latinos como inglés, francés, español, alemán, esperanto, etc: /([A-Za-zÀ-ʰ])[A-Za-zÀ-ʰ]*/g
Sin ofender a nadie de gambas, me has dejado " loco " con tus explicaciones, y lo de ofender me refiero a que con Python temas de texto son sinceramente super potente.
Y pido disculpa desde ya por si me meto donde no debo. ---Perdón, vale---
|
#4 Jueves, 05 Septiembre 2019, 11:35 |
|
|
Grandamakulo
Analista Programador
Registrado: Enero 2016
Mensajes: 311
Edad: 55 Ubicación: En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
|
Re: RegEx Y Los «flags»
Hola, de nuevo:
Bueno, pues no lo he podido hacer con gambas, pero dejo una muestra de un pequeño widget en javascript —con su html y css asociado, «pa» poder usarlo bonito, pero sin body ni demás parafernalia, para poder integrarlo en una html mayor—.
Estimado «Crustáceo Feliz» , espero que la locura con mis explicaciones no haya sido debida a mi natural farragosidad.
En fin, os dejo el código de un contador de palabras muy muy simple y otro con estrógenos:
<div>
<textarea onkeyup="Estadisticas()" id="Texto" ></textarea>
<label id="Palabras"></label>
<script>
function Estadisticas() {
var strTexto = Texto.value;
var Resultado = 0
var pttPalabras = /([A-Za-z0-9\u00C0-\u02B8])[A-Za-z0-9\u00C0-\u02B8]*/g;
try {
Resultado = strTexto.match(pttPalabras).length;
var P = Resultado;
}
catch(err) {
Resultado = 0;
}
document.getElementById("Palabras").innerHTML = "Palabras:" + Resultado;
}
</script>
</div>
<div class="crqt" id="Pral" onload="Estadisticas()">
<form class="crqt" id="Escrito">
<textarea onkeyup="Estadisticas()" id="Texto" class="crqt">Escribe aquí</textarea>
</form>
<form class="crqt" id="Etiquetas">
<label id="Palabras" ></label>
<label id="Matrices" ></label>
<label id="Caracteres" ></label>
<label id="Letras" ></label>
<label id="Parrafos" ></label>
<label id="Silabas" ></label>
<label id="Frases" ></label>
<label style="border-top: solid thin">LEGIBILIDAD</label>
<label id="Fdez-Huerta1959" ></label>
<label id="Gtz-Polini1972" ></label>
<label id="Szigriszt1993" ></label>
</form>
<script>
function Estadisticas() {
var strTexto = Texto.value;
var Resultado = 0
var pttPalabras = /([A-Za-z0-9\u00C0-\u02B8])[A-Za-z0-9\u00C0-\u02B8]*/g;
var pttMatrices = /./g;
var pttCaracteres= /\S/g;
var pttLetras = /[A-Za-z0-9\u00C0-\u02B8]/g;
var pttParrafos = /[\n][^\n]/g;
var pttSilabas = /[aeo]h[iu]|[iu]h[aeo]|[aeo][iu]|[aeo][y]|[y]|[íú]|[iu][^aeo]|[aeo]|[áéíóú]|[q|g]ui[aeo]/gi
var pttFrases = /[.?!][^.?!]/g;
try {
Resultado = strTexto.match(pttPalabras).length;
var P = Resultado;
}
catch(err) {
Resultado = 0;
}
document.getElementById("Palabras").innerHTML = "Palabras : " + Resultado;
try {
Resultado = strTexto.match(pttMatrices).length;
}
catch(err) {
Resultado = 0;
}
document.getElementById("Matrices").innerHTML = "Matrices : " + Resultado;
try {
Resultado = strTexto.match(pttCaracteres).length;
}
catch(err) {
Resultado = 0;
}
document.getElementById("Caracteres").innerHTML= "Caracteres : " + Resultado;
try {
Resultado = strTexto.match(pttLetras).length;
var L = Resultado;
}
catch(err) {
Resultado = 0;
}
document.getElementById("Letras").innerHTML = "Letras : " + Resultado;
try {
Resultado = strTexto.match(pttParrafos).length;
}
catch(err) {
Resultado = 0;
}
document.getElementById("Parrafos").innerHTML = "Párrafos : " + Resultado;
try {
Resultado = strTexto.match(pttSilabas).length;
var S = Resultado;
}
catch(err) {
Resultado = 0;
}
document.getElementById("Silabas").innerHTML = "Sílabas —prov.— : " + Resultado;
try {
Resultado = strTexto.match(pttFrases).length;
var F = Resultado;
}
catch(err) {
Resultado = 0;
}
document.getElementById("Frases").innerHTML = "Frases —prov.— : " + Resultado;
Resultado = 206.84-60*S/P-1.02*P/F;
Resultado = Math.round(Resultado);
if (isNaN(Resultado)) {
Resultado = 0;
}
document.getElementById("Fdez-Huerta1959").innerHTML= "Fdez-Huerta 1959: " + Resultado;
Resultado = 95.2-9.7*L/P-0.35*P/F;
Resultado = Math.round(Resultado);
if (isNaN(Resultado)) {
Resultado = 0;
}
document.getElementById("Gtz-Polini1972").innerHTML= "Gtz-Polini 1972 : " + Resultado;
Resultado = 206.835-62.3*S/P-P/F;
Resultado = Math.round(Resultado);
if (isNaN(Resultado)) {
Resultado = 0;
}
document.getElementById("Szigriszt1993").innerHTML= "Szigriszt 1993 : " + Resultado;
}
</script>
<style type="text/css">
.crqt {
background-color: black;
color: rgb(0, 255, 0);
font-family: monospace;
font-size: 14px;
border-style: solid;
border-width: thin;
border-color: rgb(0, 255, 00);
}
form label {
display: inline-block;
width: 200px;
}
textarea {
width: 98%;
height: 98%;
}
#Pral {
width: 600px;
height: 190px;
}
#Escrito {
width: 64%;
height: 99%;
float: left;
}
#Etiquetas {
width: 35%;
float: right;
}
</style>
</div>
última edición por Grandamakulo el Martes, 10 Septiembre 2019, 09:34; editado 6 veces
|
#5 Martes, 10 Septiembre 2019, 09:25 |
|
|
gambafeliz
Analista Programador
Registrado: Julio 2019
Mensajes: 830
Edad: 54
|
Re: RegExp Y Los «flags»
|
#6 Martes, 10 Septiembre 2019, 11:02 |
|
|
shordi
Analista Programador
Registrado: Septiembre 2009
Mensajes: 4982
Edad: 64 Ubicación: Albacete
|
Re: RegExp Y Los «flags»
Yo no mentero. A ver:
Sin haber probado tu código, ya que tengo cuatro ediciones del quijote y cada una tiene un número de palabras distinto (con la notas, y demás), he copiado el primer capítulo del único que no tenía notas a un fichero de texto.
Lo he incorporado a una pequeña aplicación de recuento que dejo aquí.
¿Qué diferencia da tu código respecto a ésto?
Saludos
Descripción: |
|
Descargar |
Nombre del archivo: |
quijote-0.0.1.tar.gz |
Tamaño: |
15.96 KB |
Descargado: |
51 veces |
Descripción: |
|
Descargar |
Nombre del archivo: |
quijote-0.0.1.tar.gz |
Tamaño: |
15.96 KB |
Descargado: |
51 veces |
Descripción: |
|
Descargar |
Nombre del archivo: |
quijote-0.0.1.tar.gz |
Tamaño: |
15.96 KB |
Descargado: |
51 veces |
=================== No podemos regresar
|
#7 Martes, 10 Septiembre 2019, 12:45 |
|
|
Grandamakulo
Analista Programador
Registrado: Enero 2016
Mensajes: 311
Edad: 55 Ubicación: En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
|
Re: RegExp Y Los «flags»
Hola, Shordi:
Pues muchísimas gracias por tu aporte, que me parece estupendísimo.
Pero, efectivamente, hay diferencias.
En primer lugar, y esto no lo puedo comparar por las limitaciones de RegExp de gambas, no sé si un bucle con gambas es más rápido que la evaluación en C —o C# o C++ o cualquier lenguaje en el que euiera que esté hecha la librería ¿LOGO ?— de RegExp.
En segundo lugar, la flexibilidad de las RegExp frente a los algoritmos específicos de búsqueda que hay que implementar para cada caso.
Y en tercer lugar, un ejemplo —probado en gambas Playground, que hasta que no llegue a casa no podré ver el ejemplo con más detalle—:
Es decir, los caracteres especiales en español hay que tratarlos aparte.
Volviendo al tema de la flexibilidad y de inventar algoritmos, por ejemplo, la contabilidad de palabras es errónea empleando los espacios, ya que, por ejemplo, no considera como palabras las separadas por un punto y aparte. O la dificultad para contar sílabas. De hecho, para ver si cuenta bien «de verdad» uso unos patrones «problemáticos» de unas cincuenta palabras sobre los que hago estadísticas a mano.
Cuando llegue a casa, comparo varios patrones para mostrarte lo que quiero decir.
Un saludo,
PS.—La contabilidad de palabras por espacios se refiere a este trozo de tu código —por si no me he explicado, que uno es lioso de natura—:
última edición por Grandamakulo el Miercoles, 11 Septiembre 2019, 09:21; editado 1 vez
|
#8 Miercoles, 11 Septiembre 2019, 09:19 |
|
|
Grandamakulo
Analista Programador
Registrado: Enero 2016
Mensajes: 311
Edad: 55 Ubicación: En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
|
Re: RegExp Y Los «flags»
Bueno, Shordi, lo he podido probar con gambas Playground haciendo unas mínimas modificaciones que no afectan a los algoritmos.
He usado un texto pequeño de prueba para que podamos contar a mano:
Public Sub Main()
Dim s As String
Dim ar As String[]
Dim var As New Variant[]
Dim n, palabras, caracteres, letras, alnum, noalnum, asci, noasci As Integer
Dim presen as string
s = "Mi última bala\n\nEstoy sobre la cabina oxidada de un camión; él, a unos metros, sobre una cisterna.\nSin munición, sin salida. Rodeados de no vivos.\n—Tírame tu pistola —me grita.— ¡Confía en mí!\n—¡¿Qué?!\n—Hay un depósito de propano. Moriremos matando.\nSe la lancé. El muy cabrón se suicidó."
For n = 0 To Len(s)
If IsAlnum(s[n]) Then
Inc alnum
Else
Inc noalnum
Endif
If IsAscii(s[n]) Then
Inc asci
Else
Inc noasci
Endif
Next
ar = Split(s, " ")
palabras = ar.count
For n = 0 To ar.Max
caracteres += Len(ar[n])
Next
presen &= "Longitud total " & String.Byte(s, Len(s)) & gb.NewLine
presen &= "-----------------------------------------" & gb.NewLine
presen &= "Letras o Números " & Str(alnum) & gb.NewLine
presen &= "Caracteres " & Str(noalnum) & gb.NewLine
presen &= "Total " & Str(noalnum + alnum) & gb.NewLine
presen &= "-----------------------------------------" & gb.NewLine
presen &= "Caracteres ASCII " & Str(asci) & gb.NewLine
presen &= "Caracteres NO ASCII " & Str(noasci) & gb.NewLine
presen &= "Total " & Str(asci + noasci) & gb.NewLine
presen &= "-----------------------------------------" & gb.NewLine
presen &= "Palabras " & Str(palabras) & gb.NewLine
presen &= "Longitud palabras (sin espacios) " & Str(caracteres) & gb.NewLine
presen &= "Palabras + Espacios " & Str(caracteres + palabras) & gb.NewLine
Print presen
End
El resultado es:
Longitud total 314
-----------------------------------------
Letras o Números 203
Caracteres 111
Total 314
-----------------------------------------
Caracteres ASCII 268
Caracteres NO ASCII 46
Total 314
-----------------------------------------
Palabras 44
Longitud palabras (sin espacios) 270
Palabras + Espacios 314
Con el html, me sale:
Palabras : 50
Matrices : 281
Caracteres : 238
Letras : 215
Párrafos : 6
Sílabas —prov.— : 96
Frases —prov.— : 9
LEGIBILIDAD
Fdez-Huerta 1959: 86
Gtz-Polini 1972 : 52
Szigriszt 1993 : 82
Y a mano:
Palabras: 50
Matrices: 281
Caracteres: 238
Párrafos: 7
—Vale, párrafos no va bien, pero en ello estamos —
|
#9 Miercoles, 11 Septiembre 2019, 09:47 |
|
|
shordi
Analista Programador
Registrado: Septiembre 2009
Mensajes: 4982
Edad: 64 Ubicación: Albacete
|
Re: RegExp Y Los «flags»
Ok. Ni se me había ocurrido lo de los enter, corregido eso y una discrepancia en el uso de la clase string, para tratar UTF8, queda así:
Public Sub Main()
Dim s As String
Dim ar As String[]
Dim var As New Variant[]
Dim n, palabras, caracteres, letras, alnum, noalnum, asci, noasci As Integer
Dim presen As String
s = "Mi última bala\n\nEstoy sobre la cabina oxidada de un camión; él, a unos metros, sobre una cisterna.\nSin munición, sin salida. Rodeados de no vivos.\n—Tírame tu pistola —me grita.— ¡Confía en mí!\n—¡¿Qué?!\n—Hay un depósito de propano. Moriremos matando.\nSe la lancé. El muy cabrón se suicidó."
For n = 0 To String.Len(s)
If IsAlnum(s[n]) Then
Inc alnum
Else
Inc noalnum
Endif
If IsAscii(s[n]) Then
Inc asci
Else
Inc noasci
Endif
Next
ar = Split(s, " \n", "", True)
palabras = ar.count
For n = 0 To ar.Max
caracteres += String.Len(ar[n])
Next
presen &= "Longitud total " & String.len(s) & gb.NewLine
presen &= "-----------------------------------------" & gb.NewLine
presen &= "Letras o Números " & Str(alnum) & gb.NewLine
presen &= "Caracteres " & Str(noalnum) & gb.NewLine
presen &= "Total " & Str(noalnum + alnum) & gb.NewLine
presen &= "-----------------------------------------" & gb.NewLine
presen &= "Caracteres ASCII " & Str(asci) & gb.NewLine
presen &= "Caracteres NO ASCII " & Str(noasci) & gb.NewLine
presen &= "Total " & Str(asci + noasci) & gb.NewLine
presen &= "-----------------------------------------" & gb.NewLine
presen &= "Palabras " & Str(palabras) & gb.NewLine
presen &= "Longitud palabras (sin espacios) " & Str(caracteres) & gb.NewLine
presen &= "Palabras + Espacios " & Str(caracteres + palabras) & gb.NewLine
Print presen
End
Con esto me da este resultado:
Longitud total 288
-----------------------------------------
Letras o Números 187
Caracteres 102
Total 289
-----------------------------------------
Caracteres ASCII 248
Caracteres NO ASCII 41
Total 289
-----------------------------------------
Palabras 50
Longitud palabras (sin espacios) 238
Palabras + Espacios 288
(Nótese la discrepancia de un caracter en la cuenta total (función string.len) y el sumatorio de las otras funciones. Ignoro de dónde viene.)
El tema es que no sé lo que estamos contando cada uno. ¿Qué son Matrices? En tu cuenta ¿cuál es tamaño total del texto? ¿Cómo lo cuadras? ¿A qué llamas "caracteres"?, etc. (Quiero decir algo así como matrices + espacios - palabras partido por dos) y no voy a preguntar quienes son los señores Fernández Huerta ni compañía...
O sea que confusión total...
Saludos
=================== No podemos regresar
última edición por shordi el Miercoles, 11 Septiembre 2019, 17:29; editado 2 veces
|
#10 Miercoles, 11 Septiembre 2019, 17:17 |
|
|
|
Temas parecidos
Temas parecidos
|
Página 1 de 2
|
Usuarios navegando en este tema: 0 registrados, 0 ocultos y 1 invitado Usuarios registrados conectados: Ninguno
|
No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas No puede adjuntar archivos Puede descargar archivos No puede publicar eventos en el calendario
|
|
|
|
|