Estrarre Stringhe specifiche con simbolo



  • Estrarre Stringhe specifiche con simbolo
    di Antonello (utente non iscritto) data: 24/06/2017 13:24:33

    Buon giorno ragazzi ho un problema con l'estrazione di stringhe in excel, faccio un esempio, ho:

    1 - marco maria angelo | marco rocco leo | giovanni andrea
    2 - marco maria angelo | marco rocco leo | giovanni giulio | Graziano giovanni |
    3 - rocco rita | francesco mario |

    voglio ottenere:

    1 - marco maria angelo | marco rocco leo
    2 - marco maria angelo | marco rocco leo | giovanni giulio
    3 - rocco rita | francesco mario

    praticamente voglio eliminare tutto ciò che c'è dopo l'ultimo simbolo " | " simbolo compreso, ho 5000 stringhe così e vorrei automatizzare il processo.
    Le ho provate i tutti i modi ma non riesco a venirne a capo. C'è qualcuno che può aiutarmi? Grazie in anticipo



  • di Vecchio Frac data: 24/06/2017 13:39:39

    cit. "Le ho provate i tutti i modi"
    ---> Mi vien da chiederti cosa hai provato e come, come agli esami quando ti metti in un vespaio per una mezza parola in più e il prof comincia ad approfittarne ^_^
    Comunque: fai un ciclo sulle celle del range, usa Split sulla pipe per ricavarne i diversi item, che recuperi in una stringa tranne l'ultimo, cioè quello che ha indice uguale all'ubound della matrice, scrivi nella cella che ti interessa (sequenzialmente immagino) questa nuova stringa e il gioco è fatto.





  • di Vecchio Frac data: 24/06/2017 13:42:13

    Comunque non è l'unico modo.
    Puoi anche usare la comoda funzione che ricerca un carattere all'indietro, ne recuperi l'indice quando trovi la pipe, quindi costruisci la stringa dal primo carattere della stessa fino a quello appena trovato, inserisci la cella nella stringa, e sei ancora più a posto ^_^





  • di Vecchio Frac data: 24/06/2017 13:44:21

    E se uno volesse fare il figo, potrebbe usare un'espressione regolare per la ricerca dell'ultimo carattere pipe e da qui ricavarne l'indice per estrarre eccetera eccetera ^_^
    Ci sono in effetti molti modi diversi.





  • di alfrimpa data: 24/06/2017 17:04:48

    Non voglio fare il figo ma propongo una banalissima funzioncina (che Vecchio Frac sicuramente mi correggerà) che dovrebbe fare quello che è stato chiesto.

    Alfredo 
     
    Function prova(a As Range)
    Dim i As Integer
    For i = Len(a.Value) To 1 Step -1
        If Mid(a.Value, i, 1) = "|" Then
            prova = Left(a.Value, i - 1)
            Exit For
        End If
    Next i
    End Function
    
    






  • di Vecchio Frac data: 24/06/2017 17:11:41

    Non contesto, funziona... a essere pinoli sarebbe da aggiustare perchè se nella stringa non c'è alcuna pipe restituisce 0: aggiustala aggiungendo il tipo String e vai tranquillo: Function prova(a As Range) As String.

    Comunque l'idea della regex è carina ^_^





  • di alfrimpa data: 24/06/2017 17:18:52

    Francesco io i pinoli li mangio

    Cit. "se nella stringa non c'è alcuna pipe restituisce 0: aggiustala aggiungendo il tipo String"

    E qualcosa all'utente non gliela vogliamo far fare?

    Un caro saluto

    Alfredo

    P.S. Le Regex? Vade retro Satana!!!! ; tutte le volte che ho cercato di affrontare il tema ho dovuto farmi una flebo di Aulin





  • di Vecchio Frac data: 24/06/2017 17:30:54

    Ma LOL...

    Qualche risorsa.
    Il meglio del meglio: www.rexegg.com/

    Ma anche in italiano: www.regexplanet.com/advanced/dotnet/index.html
    E pure (un po' datato): nicolaiarocci.com/introduzione-alle-regular-expression-prima-parte/

    In particolare per VBA/VBScript: www.regular-expressions.info/vbscript.html

    Poi ci sono i siti di "regex online". Necessari ^_^





  • di Gianfranco data: 24/06/2017 18:05:50

    ciao
    tanto per partecipare

    in C3 la frase

    =SE(SE.ERRORE(TROVA("|";C3););SINISTRA(C3;LUNGHEZZA(ANNULLA.SPAZI(C3))-LUNGHEZZA(ANNULLA.SPAZI(DESTRA(SOSTITUISCI(C3;"|";RIPETI(" ";200));200)))-1);C3)




  • di alfrimpa data: 24/06/2017 18:07:42

    Gianfrà ma come fai a pensarle?

    Un caro saluto

    Alfredo





  • di Vecchio Frac data: 24/06/2017 18:11:49

    Buono
    Però lascia un'ultima pipe nella stringa "pippo | paperino" (cioè quando c'è uno spazio dopo una pipe: in "pippo |paperino" il risultato restituito è corretto).





  • di Gianfranco data: 24/06/2017 18:20:43

    ciao
    Vecchio Frac

    mmmmmmmm!!!!
    ho ricontrollato nessuna pipe
    puoi avere problemi se non c'è lo spazio dopo la pipe

    esempio

    pappa | pippo
    va bene

    Pappa |pippo
    ti elimina un carattere in più

    suppongo venga sempre scritta così


    Al
    te l'ho detto
    chi come me è un novizio delle formule
    si ingegna



  • di alfrimpa data: 24/06/2017 18:51:35

    Cit. "chi come me è un novizio delle formule si ingegna"

    Vorrei essere novizio come te.





  • di Gianfranco data: 24/06/2017 18:56:01

    cavolo
    ho postato la formula
    di prova
    quella che uso io è


    =ANNULLA.SPAZI(SE(SE.ERRORE(TROVA("|";C3););SINISTRA(C3;LUNGHEZZA(ANNULLA.SPAZI(C3))-LUNGHEZZA(ANNULLA.SPAZI(DESTRA(SOSTITUISCI(C3;"|";RIPETI(" ";200));200)))-2);C3))

    annulla spazi
    perché se la pipe è l'ultima lettera ci sono due spazi da eliminare
    mentre se è in mezzo alle parole ce ne sono tre

    ho optato per il due ed eliminati gli spazi iniziali e finale
    per non incorrere nel solito errore in caso di cerca vert o simili

    scusate



  • di Vecchio Frac data: 24/06/2017 19:15:55

    cit. "Vorrei essere novizio come te."
    ---> Mi associo, vale anche per me :)





  • di scossa data: 24/06/2017 22:58:15

    cit. V.F.: "Comunque l'idea della regex è carina ^_^"

    Ciao,

    ad esempio questo pattern: s*|(s*w+s*)*$

    vedi UDF sotto.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)

     
    Public Function CancLastPipe(ByVal sString As String) As String
      'by scossa
      'w w w .excelvba.it/Forum/thread.php?f=1&t=12076
        
      Dim re As RegExp  'richiede il riferimento a Microsft VBscript Regular Exspression 5.5
                        'altrimenti
                        'Dim re as Object
                        
      Dim reMatch As MatchCollection  'richiede il riferimento a Microsft VBscript Regular Exspression 5.5
                                      'altrimenti
                                      'Dim reMatch as Object
      
      Dim sMatched As String
      Dim sPatt As String
      
      On Error GoTo Sost_Error_
      
      Set re = New RegExp             'richiede il riferimento a Microsft VBscript Regular Exspression 5.5
                                      'altrimenti
                                      'set re = CreateObject("vbscript.regexp")
      
      With re
        .Global = True
        sPatt = "s*|(s*w+s*)*$"
        .IgnoreCase = True
        .Pattern = sPatt
        If .Test(sString) Then
          Set reMatch = .Execute(sString)
          sMatched = reMatch.Item(0)
          CancLastPipe = .Replace(sString, "")
        Else
          CancLastPipe = sString
        End If
      End With
      On Error GoTo 0
    
    Sost_Error_:
    
      Set re = Nothing
      Set reMatch = Nothing
    
    End Function



  • di Vecchio Frac data: 24/06/2017 23:43:23

    Bene, sapevo che Scossa si sarebbe stuzzicato un pochino ^_^
    Io avevo pensato a un pattern così:

    re.Pattern = "|(?!.*|)"







  • di scossa data: 25/06/2017 08:58:18

    Ciao,

    cit. V.F.: "|(?!.*|)"

    mi sembra piuttosto impreciso ..... prova a sostituirlo al mio e vedrai che i risultati non sono quelli voluti.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Vecchio Frac data: 25/06/2017 09:32:58

    Vabbè, mi sembrava che funzionasse... ma il concetto (usare regex) rimane ^_^
     
    Option Explicit
    
    Sub test()
    Dim re As Object, v As Variant, arr As Variant
    
        Set re = CreateObject("VbScript.regexp")
        re.Global = True
        re.Pattern = "|(?!.*|)"
        
        arr = Array("Hello", "Hello | world ", "Hello| world |", "Hello | world | hello")
        For Each v In arr
            re_execute re, (v)
        Next
        
    End Sub
    
    Private Sub re_execute(re As Object, s As String)
    Dim ma As Object
        For Each ma In re.Execute(s)
            Debug.Print s, "in pos. "; ma.firstindex, "--> "; Left(s, ma.firstindex - 1)
        Next
        
    End Sub