Autore Topic: [Risolto] Uso del metodo replace di regexp  (Letto 780 volte)

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
[Risolto] Uso del metodo replace di regexp
« il: 04 Gennaio 2022, 16:12:09 »
Non conoscendo le espressioni regolari, ci sto diventando scemo:   :hard:

ho necessità di tramutare in modo dinamico una stringa che può essere:
Codice: [Seleziona]
"===== 23.8.1.1 Progetto Diagramma in Linea ====="
ma anche:
Codice: [Seleziona]
"===== 1 Primo Capitolo ====="
oppure:
Codice: [Seleziona]
"===== 1.2.1 Qualsiasi cosa ====="
o anche:
Codice: [Seleziona]
"===== 12.21.1.15 Qualsiasi cosa ====="
e via discorrendo...

in queste stringhe:

Codice: [Seleziona]
"k23/k23.8/k23.8.1/k23.8.1.1"

"k1"

"k1/k1.2/k1.2.1"

"k12/k12.21/k12.21.1/k12.21.1.15"

Qualcuno la fuori che conosce il componente gb.pcre
http://gambaswiki.org/wiki/comp/gb.pcre/regexp

e i metodi match e replace di regexp, può cortesemente aiutarmi?

 :ciao:
« Ultima modifica: 07 Gennaio 2022, 22:28:23 da Gianluigi »
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.311
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #1 il: 04 Gennaio 2022, 16:34:25 »
... espressioni regolari...

e i metodi match e replace di regexp...

Cheeee ?

« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #2 il: 04 Gennaio 2022, 17:35:56 »
 :P

Ho fatto un piccolissimo passo avanti ma non mi riesce di escludere la parte non numerica e anche il numero spuro.
Anche all'inizio penso che sarebbe bene usare le regexp per togliere gli spazi...

Comunque posto nella speranza che qualcuno abbia un'ispirazione:

per il codice vedere più avanti

 :ciao:
« Ultima modifica: 05 Gennaio 2022, 14:19:52 da Gianluigi »
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline cogier

  • Gambero
  • **
  • Post: 57
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #3 il: 04 Gennaio 2022, 18:08:28 »
Non ci sono 'regexp' qui, ma questo funziona.

Codice: [Seleziona]
Public Sub Form_Open()

  Print GetKIP("===== 23.8.1.1 Progetto Diagramma In Linea =====")
  Print GetKIP("===== 1 Primo Capitolo =====")
  Print GetKIP("===== 1.2.1 Qualsiasi cosa =====")
  Print GetKIP("===== 12.21.1.15 Qualsiasi cosa =====")

End

Public Sub GetKIP(sLine As String) As String

  Dim sNew, sWork As String
  Dim iLoop, iLetter As Integer
  Dim sHold As New String[]

  For iLetter = 1 To Len(sLine)
    If IsNumber(Mid(sLine, iLetter, 1)) Then sWork &= Mid(sLine, iLetter, 1)
  Next

  sWork = "k" & sWork
  sHold = Split(sWork, ".")

  For iLoop = 0 To sHold.Max
    If iLoop = 0 Then sNew &= sHold[0] & "/"
    If iLoop = 1 Then sNew &= sHold[0] & "." & sHold[1] & "/"
    If iLoop = 2 Then sNew &= sHold[0] & "." & sHold[1] & "." & sHold[2] & "/"
    If iLoop = 3 Then sNew &= sHold[0] & "." & sHold[1] & "." & sHold[2] & "." & sHold[3] & "/"
  Next

  Return Left(sNew, -1)

End

Uscita: -

k23/k23.8/k23.8.1/k23.8.1.1
k1
k1/k1.2/k1.2.1
k12/k12.21/k12.21.1/k12.21.1.15

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #4 il: 04 Gennaio 2022, 18:13:48 »
@cogier

ti ringrazio molto, ma io sto cercando una soluzione con le regexp  :-\
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline pastrank

  • Maestro Gambero
  • ****
  • Post: 265
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #5 il: 04 Gennaio 2022, 23:12:05 »
@cogier

ti ringrazio molto, ma io sto cercando una soluzione con le regexp  :-\

Mi pare che tu stia usando la sintassi che usa per LIKE piuttosto che quella piu' adatta alle REGEX. Non ho pratica con queste su Gambas (poco anche in Python a dire il vero), ma forse la cosa piu' semplice sarebbe dividere il testo riga per riga, almeno ti eviti complicazioni con le opzioni, e poi cercare il blocco comprensivo dei 4 segni di uguale dalle parti. Se ti basta quello, lo trovi con qualcosa tipo
Codice: [Seleziona]
regexp(text, "( ====|====) .* ====) 
o forse meglio ancora meglio sarebbe usare i capturing groups, che nel caso di una riga tipo
Codice: [Seleziona]
 ==== 1.21.211 ====
potrebbero essere rintracciati con una regexp tipo
Codice: [Seleziona]
[\s]{0,1}==== ([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,2}) ====
che sembra complicata, ma in realta' sta a significare una riga con uno spazio o meno all'inizio, poi quattro segni di uguale, uno spazio, poi ci sono tre gruppi di uno o due numeri separati da un punto, altro spazio e infine altri quattro uguale. Manca ancora qualche cosa, tipo il dire se quello deve essere l'inizio della riga etc etc. La soluzione ideale sarebbe usare la regexp multilinea, iterare i Match e sostituire i capturing groups. La cosa piu' semplice rimane la prima, secondo me, anche perche' come dicevo con le regex di Gambas ho zero esperienze. Ricorda comunque il racconto: Avevo un problema, ho cercato di risolverlo con le regex, adesso ho due problemi. Di sicuro farai molti tentativi su siti tipo https://regex101.com
« Ultima modifica: 04 Gennaio 2022, 23:13:07 da pastrank »

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #6 il: 04 Gennaio 2022, 23:31:54 »
@pastrank

ti ringrazio molto della risposta, ora sono stanco e vado a dormire che domani sono di ramazza, domani provo con i tuoi suggerimenti.

Per ora ho questa soluzione, cosa te ne pare?
Lo so poco convincente...

Per il codice vedere più avanti...

 :D Carino il detto

 :ciao:
« Ultima modifica: 05 Gennaio 2022, 14:20:54 da Gianluigi »
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline pastrank

  • Maestro Gambero
  • ****
  • Post: 265
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #7 il: 05 Gennaio 2022, 03:06:48 »
Per ora ho questa soluzione, cosa te ne pare?

Perche' no? Casomai cambierei i [1-9][1-9][1-9] in [1-9]{1,3} (o forse intendi [0-9]?), solo per ridurre la lunghezza delle righe. Per il resto, se non hai da processare milioni di righe (le regex sono piuttosto lente), se va bene lascerei stare.

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #8 il: 05 Gennaio 2022, 08:39:05 »
Per ora ho questa soluzione, cosa te ne pare?

Perche' no? Casomai cambierei i [1-9][1-9][1-9] in [1-9]{1,3} (o forse intendi [0-9]?), solo per ridurre la lunghezza delle righe. Per il resto, se non hai da processare milioni di righe (le regex sono piuttosto lente), se va bene lascerei stare.

Dovrebbero essere poche pagine A4
Capitoli zero non ce ne sono.
Il significato dell'espressione regolare è:
Trovami quattro numeri di 2 oppure (|) 1 cifra divisi da un punto e sostituiscili con k + il primo numero seguito da /k + primo numero + punto ecc. ecc.
Trovami tre numeri...
Ho cercato di farla diversamente ma non ci sono ancora riuscito

Ultimo sforzo:

Per il codice vedere più avanti...

Ora corro a lavorare  :ciao:
« Ultima modifica: 05 Gennaio 2022, 14:21:47 da Gianluigi »
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #9 il: 05 Gennaio 2022, 14:25:53 »
Per ora ho questa soluzione, cosa te ne pare?

Perche' no? Casomai cambierei i [1-9][1-9][1-9] in [1-9]{1,3} (o forse intendi [0-9]?), solo per ridurre la lunghezza delle righe. Per il resto, se non hai da processare milioni di righe (le regex sono piuttosto lente), se va bene lascerei stare.

Si avevi ragione ci sono capitoli .0 pertanto occorre cercare [0-9]

Invece riguardo alla riduzione non ci sono riuscito  :-\

Questo è il massimo che sono riuscito a fare
Codice: [Seleziona]
Public Sub Main()

  Print Capitolo("  =====   23.8.1.1 Progetto Diagramma in Linea numero 2 =====")
  Print Capitolo("  =====   23.8.1 Progetto Diagramma in Linea numero 2 =====")
  Print Capitolo("  =====   23.8 Progetto Diagramma in Linea numero 2 =====")
  Print Capitolo("  =====   23 Progetto Diagramma in Linea numero 2 =====")
  Print Capitolo("  =====   1 Progetto Diagramma in Linea numero 2 =====")
  Print Capitolo("===== 12.4.4.2 Eigene Dialoge - Projekt 2 =====")
  Print Capitolo("===== 1.1 Capitolo =====")
  Print Capitolo("  =====  1.1.3   Gambas im Internet ===== ")
  Print Capitolo("===== 13 Capitolo =====")
  Print Capitolo("===== 10.1 Capitolo =====")
  Print Capitolo("===== 22.5.4  Capitolo =====")
  Print Capitolo("=====24.7.8.4 Capitolo =====") ' <--------------------------------così prima non funzionava, ora funziona
  Print Capitolo("=====  22.10.0.2   Methoden der Klasse Memcached ===== ") ' <-----c'è anche il capitolo 0 ;-D
  Print Capitolo("=====24.7.8.4Capitolo =====")

End

Private Sub Capitolo(value As String) As String

  '' così sembra funzionare tutto bene
  If Trim(value) Begins "=====" Then
    value = Replace$(value, "=====", "")
    If RegExp.Match(value, "([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9])") Then
      Print "MATCH"
      value = RegExp.Replace(value, "([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9])", " k&1/k&1.&2/k&1.&2.&3/k&1.&2.&3.&4 ")
    Else If RegExp.Match(value, "([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9])") Then
      Print "MATCH"
      value = RegExp.Replace(value, "([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9])", " k&1/k&1.&2/k&1.&2.&3 ")
    Else If RegExp.Match(value, "([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9])") Then
      Print "MATCH"
      value = RegExp.Replace(value, "([0-9][0-9]|[0-9]).([0-9][0-9]|[0-9])", " k&1/k&1.&2 ")
    Else If RegExp.Match(value, "([0-9][0-9]|[0-9])") Then
      Print "MATCH"
      value = RegExp.Replace(value, "([0-9][0-9]|[0-9])", " k&1 ")
    Endif
    value = Scan(value, "* * *")[1]
  Endif
  Return value

End


Con questo codice considero il quesito risolto, pertanto questa sera correggo il titolo aggiungendo [Risolto] anche se la discussione va avanti di parecchi post   ;)
« Ultima modifica: 07 Gennaio 2022, 22:27:28 da Gianluigi »
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline pastrank

  • Maestro Gambero
  • ****
  • Post: 265
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #10 il: 05 Gennaio 2022, 23:23:04 »
Si avevi ragione ci sono capitoli .0 pertanto occorre cercare [0-9]

Io stavo a pensare al numero 10 :-) E quello che dicevo, in pratica, era che un capturing group tipo

Codice: [Seleziona]
[0-9]|[0-9])

Lo leggo come Un numero tra 0 e 9 oppure un numero tra 0 e 9, quindi basterebbe ([0-9])

E ancora

Codice: [Seleziona]
([0-9][0-9]|[0-9])

Starebbe a dire due numeri (da 10 a 99) oppure un numero, da 0 a 9. Potrebbe essere ridotto a ([0-9]{1,2})

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #11 il: 05 Gennaio 2022, 23:43:28 »
Si avevi ragione ci sono capitoli .0 pertanto occorre cercare [0-9]

Io stavo a pensare al numero 10 :-)
No il dieci funzionava, ma non funzionava lo zero
Non so cosa avevo visto, ma anche per logica [1-9][1-9] non può funzionare, tuttalpiù [1-9][0-9]  :-[
Citazione
E quello che dicevo, in pratica, era che un capturing group tipo


Codice: [Seleziona]
[0-9]|[0-9])

Lo leggo come Un numero tra 0 e 9 oppure un numero tra 0 e 9, quindi basterebbe ([0-9])

E ancora

Codice: [Seleziona]
([0-9][0-9]|[0-9])

Starebbe a dire due numeri (da 10 a 99) oppure un numero, da 0 a 9. Potrebbe essere ridotto a ([0-9]{1,2})

Ti basta provare questo codice per vedere che non funziona
Codice: [Seleziona]
Public Sub Main()

  Dim value As String = "pippo19pluto"

  If RegExp.Match(value, "([0-9]{1,2})") Then
    Print "MATCH"
    value = RegExp.Replace(value, "([0-9]{1,2})", " k&1 ")
  Endif
  value = Scan(value, "* * *")[1]
  Print value

End

Credo che sia per via del fatto che per funzionare deve prima valutare due cifre oppure una cifra e non viceversa...

 :ciao:
« Ultima modifica: 06 Gennaio 2022, 00:12:00 da Gianluigi »
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline pastrank

  • Maestro Gambero
  • ****
  • Post: 265
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #12 il: 06 Gennaio 2022, 11:25:50 »
Credo che sia per via del fatto che per funzionare deve prima valutare due cifre oppure una cifra e non viceversa...

Beh, pero' la regex della riga non e' [0-9][0-9]... e' ".* ([0-9]{1,3}) .*"
Se metti quel valore come regex funziona. A occhio io ho in mente di fare una cosa, e tu un'altra, va detto che se la spiegazioni fosse questa non capirei perche' con le due ripetizioni funzioni :-)

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #13 il: 06 Gennaio 2022, 11:50:56 »
Credo che sia per via del fatto che per funzionare deve prima valutare due cifre oppure una cifra e non viceversa...

Beh, pero' la regex della riga non e' [0-9][0-9]... e' ".* ([0-9]{1,3}) .*"
Se metti quel valore come regex funziona. A occhio io ho in mente di fare una cosa, e tu un'altra, va detto che se la spiegazioni fosse questa non capirei perche' con le due ripetizioni funzioni :-)

 :ciao: pastrank,

mi sembra di essere stato chiaro, sia nel dire che non so di espressioni regolari, ma anche nella spiegazione della mia (elementare, ma comprensibilissima) espressione.
Infatti funziona

Se mi vuoi presentare un'espressione più consona e che a sua volta funzioni, sei il benvenuto, ma per ora non sono riuscito a capire cosa intendi dirmi  :-\

 :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline pastrank

  • Maestro Gambero
  • ****
  • Post: 265
    • Mostra profilo
Re:Uso del metodo replace di regexp
« Risposta #14 il: 06 Gennaio 2022, 15:34:35 »
Se mi vuoi presentare un'espressione più consona e che a sua volta funzioni, sei il benvenuto, ma per ora non sono riuscito a capire cosa intendi dirmi  :-\

Non discuto l'espressione, ma se puo' essere accorciata o resa piu' leggibile. Inoltre, se avevo un piano di usare Gambas con le pcre, sarei curioso di sapere come mai il canonico segno della ripetizione non funziona: se vado sui siti di debug online, vedo che va bene invece. Se mi sono spiegato :-)