Je dois récupérer une ligne qui comporte ce(s) terme(s) : "body":"
Voici un script qui fonctionne, qui détecte la ligne, mais qui ne me l'affiche pas....
j'ai peut-être une idée de "pourquoi il trouve la ligne sans l'afficher avec echo".
Voici le script en question :
Dim objFile, strLine,ligne
fichier = "fichier.txt"
T1 = "body" & Chr(34) & ":" & Chr(34)
Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.openTextFile(fichier, 1, false)
Dim objFSO: Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile= objFSO.OpenTextFile(fichier, 1) Do While Not objFile.AtEndOfStream strLine = objFile.ReadLine If InStr(1, strLine, T1) <> 0 Then WScript.Echo "Ligne trouvée" ligne = strLine End If
Loop objFile.Close
WScript.Echo ligne WScript.Echo "FIN"
Mon hypothèse : la longueur monstrueuse de la ligne en question.
Est-ce que "echo" a une limitation de caractères ?
« As tu essayé avec un fichier bidon dont la ligne est plus courte? »
=> En effet, tu as vu juste, j'ai créé un fichier bidon avec plusieurs lignes, dont une comportant le terme souhaité.
Et j'arrive à l'afficher.
« Ce script n'affichera qu'une ligne même s'il y en a plusieurs »
« Ce script ira jusqu'au bout du fichier, même si ça fait "longtemps" qu'il a trouvé une ligne correspondante »
=> Ce terme n’apparaît qu'une fois, donc une seule ligne.
Je pourrais donc fermer la boucle s'il la trouve.
« Au final, as tu besoin de la ligne entière ou seulement d'un morceau? »
En fait, celle ligne contient plusieurs morceaux, que je souhaite récupérer.
Et le terme recherché, est le seul à être "unique".
En résumé :
Je trouve la ligne correspondante
Je l'exploite
« Connais tu les regex? »
Je connais que de nom, et je n'ai pas envie de les connaitre...
Les morceaux à récupérer, sont entre des caractères / termes qui ne changent jamais.
Donc pour mon cas, je préfère éviter les regex.
reste le problème de la ligne "trop longue".
Je vais potasser ^^
Merci encore de ta réponse.
EDIT :
Je vais surement devoir remplacer ce terme par le même terme, précédé d'un saute de ligne.
Et un terme à la fin de la ligne, pareil.
Je pense que la longueur de la ligne sera largement réduite.
++
Comme un sage m'a dit : « en France, on a le droit de tout faire....
Faut juste ne pas se faire choper. »
Pourtant tout ce que tu as décrit est un cas d’école pour une regex.
Tu lui donnes le fichier entier, et elle te retourne directement les morceaux dont tu as besoin via une capture et des sous captures.
Si tu souhaites rester avec ta recherche ligne par ligne, je ne peux pas t’aider.
Si tu souhaites tester la regex alors, peux tu poster une ligne exemple et décrire quels morceaux extraire?
Voir cet exemple https://regex101.com/r/WIDSI5/1 Au milieu de la colonne de droite, tu peux voir la capture complète, le groupe 1 et le groupe 2
Cette partie de la syntaxe
"subject":"
veut dire que la capture commence littéralement par
"subject":"
Les parenthèses définissent le début et la fin d'un groupe.
Le point veut dire que n'importe quel caractère est accepté.
L'étoile signifie répété "indéfiniment" (enfin jusqu'à l'arrivée de la suite de la syntaxe)
Donc
"subject":"(.*)","body":"
signifie que la capture complète commence par
"subject":"
et fini par
","body":"
et que tout ce qui est entre les 2 sera mis dans le groupe 1.
Idem pour le groupe 2.
Comme je l'ai dit, je n'ai jamais fait de VBS, mais c'est proche de VBA.
Alors voilà une petite macro qui fonctionne, j'ai mis ta ligne dans le fichier Test.Txt, j'ai ajouté quelques lignes avant et aussi après.
Sub TestRegex()
Dim reg As VBScript_RegExp_55.RegExp
Dim Match As VBScript_RegExp_55.Match
Dim Matches As VBScript_RegExp_55.MatchCollection
' instanciation
Set reg = New VBScript_RegExp_55.RegExp
reg.Pattern = """subject"":""(.*)"",""body"":""(.*)"",""ad_type"""
Dim toutLeTexte As String
toutLeTexte = LireFichierTexte("C:\Temp\Test.txt")
Set Matches = reg.Execute(toutLeTexte)
For Each Match In Matches
Debug.Print "source >>", Match.Value
For i = 0 To Match.SubMatches.Count - 1
Debug.Print "[$" & i + 1 & "]", Match.SubMatches(i)
Next i
Next Match
End Sub
Public Function LireFichierTexte(ByVal MonFichier As String) As String
'https://excel-malin.com/codes-sources-vba/vba-lire-contenu-de-fichier-texte/
On Error GoTo LireFichierTexteErreur
Dim IndexFichier As Integer
IndexFichier = FreeFile()
Open MonFichier For Binary Access Read As #IndexFichier
LireFichierTexte = Space$(LOF(IndexFichier))
Get #IndexFichier, , LireFichierTexte
Close #IndexFichier
Exit Function
LireFichierTexteErreur:
Close #IndexFichier
LireFichierTexte = ""
End Function
Comme tu peux le constater sur la capture d'écran si dessous, y'a juste un petit soucis d'UTF à régler, mais sinon, ça extrait bien ce que tu veux
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
Cependant, je ne sais pas pourquoi, mais j'ai vraiment du mal avec les regex. :/
Du coup, vu que mon pote m'a fait parler de VBNet, j'ai voulu sauté le pas.
Et j'ai réussi ce que je voulais faire.
Imports System
Imports System.Text.RegularExpressions
Imports System.IO
Module Program2
Sub Main2(args As String())
' ","subject":"
' ","body":"
' ","ad_type":"
' ma ligne : message1","subject":"message2","body":"message3","ad_type":"message4
' Je souhaite donc récupérer ce qu'il a entre : ,"subject":" et ","body":"
' Je souhaite donc récupérer ce qu'il a entre : ","body":" et ","ad_type":"
' En résumé, je veux récupérer message1 et message2
Dim Term1 As String = Chr(34) & "," & Chr(34) & "subject" & Chr(34) & ":" & Chr(34)
Dim Term2 As String = Chr(34) & "," & Chr(34) & "body" & Chr(34) & ":" & Chr(34)
Dim Term3 As String = Chr(34) & "," & Chr(34) & "ad_type" & Chr(34) & ":" & Chr(34)
Dim fichiertest = "c:\users\tomce\desktop\test.txt"
Dim lines() As String = IO.File.ReadAllLines(fichiertest)
Dim ligne = lines(0)
Console.WriteLine(ligne)
Dim debut_t As Integer = ligne.IndexOf(Term1)
Dim fin_t As Integer = ligne.IndexOf(Term2)
Dim debut_d As Integer = ligne.IndexOf(Term2)
Dim fin_d As Integer = ligne.IndexOf(Term3)
Dim tr As String = Strings.Mid(ligne, debut_t + Term1.Length + 1, fin_t - debut_t - Term1.Length)
Dim dc As String = Strings.Mid(ligne, debut_d + Term2.Length + 1, fin_d - debut_d - Term2.Length)
Console.WriteLine(tr)
Console.WriteLine(dc)
System.Threading.Thread.Sleep(3000)
End Sub
End Module
Je récupère bien message1 et message2
J'ai testé sur la ligne que j'avais dès le départ : avec VBNet, pas d'erreur de longueur de ligne.
Imports System.IO
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
Dim fichierComplet As String = File.ReadAllText("C:\Temp\Test.txt")
Dim pattern As String = """subject"":""(?<sujet>.*)"",""body"":""(?<corps>.*)"",""ad_type""" 'le moteur de regex de .Net accpete les groupes avec des noms, ici "sujet" et "corps"
For Each m As Match In Regex.Matches(fichierComplet, pattern)
If m.Success Then
Console.WriteLine("Le sujet: {0}", m.Groups("sujet").Value)
Console.WriteLine("Le corps: {0}", m.Groups("corps").Value)
End If
Next
Console.ReadLine()
End Sub
End Module