Canalblog
Editer l'article Suivre ce blog Administration + Créer mon blog
Publicité
La Vache En Liberté
Publicité
Visiteurs
Depuis la création 26 459
Newsletter
Archives
27 octobre 2020

Utiliser regex en programmation Pascal

  Il s'agit d'utiliser la syntaxe "Regex"pour faire des recherches de texte équivalentes en langage Delphi Free-­Pascal de base. il s'agit pas de remplacer des composants existants ni de faire des routines exhaustives,( pas d'unicode par exemple), mais d'élaborer des fonctions pas à pas, sans privilégîer a rapidité ou la compacité.

Comme la syntaxe de Regex varie, je garderai le mieux
 
Les ancres ^ et $

  • ^Début commence par "Début"
  • fin$ termine par "fin"

En Pascal, on utilisera

pos('Début',s)=1

pos('fin',s)=length(s)+1-length('fin')

 

Les quantificateurs*, +, ? et {}

  • abc*  "ab" suivi de zéro ou plusieurs "c" -
  • abc+  "ab" suivi d'un ou plusieurs "c"
  • abc?  "ab" suivi de zéro ou un "c"
  • abc{2}  "ab" suivi de 2 "c"
  • abc{2,}  "ab" suivi de 2 (ou plus) "c"
  • abc{2,5}  "ab" suivi de 2 à 5 "c"
  • a(bc)*  un "a" suivi de zéro ou plusieurs séquences "bc"
  • a(bc){2,5}  un "a" suivi de 2 à 5 copies de la séquence "bc"

 

On ne retiendra donc qu'une seule syntaxe : a{min,max}+
Respectivement 0,-1 1,-1 0,1 2,2 2,-1 2,5 où -1 est un max indéfini.

 

L'opérateur OU : | ou []

  • a(b|c) contient un "a" suivi de "b" ou "c"
  • a[bc] même résultat.


Les classes de caractère: \d, \w, \s et .

\d un chiffre -
/\w un caractère de mot (lettres, chiffres et underscore)
-\s espace,tabulations et les sauts de ligne.
\D n'est pas \d
\W n'est pas \w
\S n'est pas \s
\$ valeur littérale de $ (idem pour ^[].$ () | * +? {}\ )
. n'importe quel caractère
\uFF caractere Asci.
\UFF unicode
\h Hexadécimal
\a diacritiques _\a(ca) cherche ca ça cà et çà si FR
\n saut de ligne (#10 = $A)
\r retour chariot (#13 = $D)
\t tabulateur (#9)
\b bordure les mots (soit début ou finde ligne, soit séparateur)
\B n'est pas \b
\1 texte du groupe de capture 1
\v séarateur décimale (. ou ,)

 

Les indicateurs

 Ces indicateurs sont  à mettre en vaziables globales.

g (global) ne tient pas compte du remplacement pourla recherche suivante.
                 Ainsi cherche "00" remplace "0" pour "00000", donne 000 et non 0.-

m (multi line):^ et $ correspondent au début et à la fin d’une ligne, au lieu de la chaîne de caractères entière

i (insensitive) rend l’expression insensible à la case (par exemple, /aBc/i correspondrait à AbC)

Langue du texte outre l'anglaisà, pou les accents et autres (æßñ¡¢¿ ). FR ES IT DE...

 

Regroupement et capture: ()

  • a(bc) crée un groupe de capture avec la valeur bc -
     

Expressions entre crochets : [] [-] [^]

  • [abc] correspond à une chaîne de caractères qui a un a ou un b ou un c (est identique à a|b|c) -
  • [a-c] exactement la même chose, littéralement tout caractère de a à c.
  • [a-fA-F0-9] = /h
  • [0-9]% une chaîne de caractères qui a un chiffre de 0 à 9 avant le signe % =:/d%
  • [^a-zA-Z] ne contient aucune lettre de a à z ou de A à Z. Dans ce cas, le ^ est utilisé comme négation de l’expression

 



Avant de.proposer des fonctions Delphi,on peut utiliiser les utilitaires de ligne de commande 
GREP.EXE, l'utilitaire de recherche de texte
 reFind.exe, l'utilitaire Rechercher et Remplacer utilisant les

GREP (Global Regular Expression Print) est un puissant programme de recherche de texte dérivé de l'utilitaire UNIX du même nom. GREP recherche un texte dans un ou plusieurs fichiers ou dans le flux d'entrée standard. La syntaxe générale de la ligne de commande GREP est grep [-<options>] <searchstring> [<files(s)>...]

reFind est un utilitaire de ligne de commande pour la recherche et le remplacement de modèles de texte Perl RegEx dans un fichier texte.
-Exemples

  • Remplacer tous les "TQuery" par "TFDQuery" dans les fichiers pas :
    refind *.pas /I /W /P:TQuery /R:TFDQuery
  • Remplacer tous les "TxxxQuery" par "TFDQuery" dans les fichiers pas et dfm :
    refind *.pas *.dfm /I /W "/P:T[A-Za-z]+Query" /R:TFDQuery-
  • Remplacer tous les "TxxxQuery" par "TQueryxxx" dans les fichiers pas et dfm :
    refind *.pas *.dfm /I /W "/P:T([A-Za-z]+)Query" /R:TQuery\1
  • Retirer tous les "Origin = xxxx" des fichiers DFM :
    refind *.dfm /L "/P:\n +Origin =.+$" "/R:"


Comment exécuter un programme en ligne de commande avec Delphi ?

https://webdevdesigner.com/q/how-do-i-run-a-command-line-program-in-delphi-67216/

   

exemple utilisant ShellExecute() :

procedure TForm1.Button1Click(Sender: TObject);
begin
ShellExecute(0, nil, 'cmd.exe', '/C find "320" in.txt > out.txt', nil, SW_HIDE);
Sleep(1000);
Memo1.Lines.LoadFromFile('out.txt');
end;

notez que l'utilisation de CreateProcess() au lieu de ShellExecute() permet un meilleur contrôle du processus.

Idéalement, vous devriez aussi appeler cela dans un thread secondaire, et appeler WaitForSingleObject() sur la poignée du processus pour attendre que le processus soit terminé. Le Sleep() dans l'exemple est juste un hack pour attendre un certain temps pour le programme commencé par ShellExecute() pour finir - ShellExecute() sera ne pas le faire. Si c'était le cas, vous ne pourriez pas par exemple simplement ouvrir une instance notepad pour éditer un fichier, ShellExecute() bloquerait votre application mère jusqu'à ce que l'éditeur soit fermé.

Variant1:

cela lancera un programme 'DOS' et récupérera sa sortie:

function GetDosOutput(CommandLine: string; Work: string = 'C:\'): string; { Run a DOS program and retrieve its output dynamically while it is running. }
var
SecAtrrs: TSecurityAttributes;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
pCommandLine: array[0..255] of AnsiChar;
BytesRead: Cardinal;
WorkDir: string;
Handle: Boolean;
begin
Result := '';
with SecAtrrs do begin
nLength := SizeOf(SecAtrrs);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SecAtrrs, 0);
try
with StartupInfo do
begin
FillChar(StartupInfo, SizeOf(StartupInfo), 0);
cb := SizeOf(StartupInfo);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE;
hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
WorkDir := Work;
Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine),
nil, nil, True, 0, nil,
PChar(WorkDir), StartupInfo, ProcessInfo);
CloseHandle(StdOutPipeWrite);
if Handle then
try
repeat
WasOK := windows.ReadFile(StdOutPipeRead, pCommandLine, 255, BytesRead, nil);
if BytesRead > 0 then
begin
pCommandLine[BytesRead] := #0;
Result := Result + pCommandLine;
end;
until not WasOK or (BytesRead = 0);
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
finally
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
end;
finally
CloseHandle(StdOutPipeRead);
end;
end;

variante 2:

 

 

Capture sortie console en [temps réel] et comment il dans un TMemo:

procedure CaptureConsoleOutput(const ACommand, AParameters: String; AMemo: TMemo);
const
CReadBuffer = 2400;
var

saSecurity: TSecurityAttributes;
hRead: THandle;
hWrite: THandle;
suiStartup: TStartupInfo;
piProcess: TProcessInformation;
pBuffer: array[0..CReadBuffer] of AnsiChar; <----- update
dRead: DWord;
dRunning: DWord;
begin
saSecurity.nLength := SizeOf(TSecurityAttributes);
saSecurity.bInheritHandle := True;
saSecurity.lpSecurityDescriptor := nil;

if CreatePipe(hRead, hWrite, @saSecurity, 0) then
begin
FillChar(suiStartup, SizeOf(TStartupInfo), #0);
suiStartup.cb := SizeOf(TStartupInfo);
suiStartup.hStdInput := hRead;
suiStartup.hStdOutput := hWrite;
suiStartup.hStdError := hWrite;
suiStartup.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
suiStartup.wShowWindow := SW_HIDE;

if CreateProcess(nil, PChar(ACommand + ' ' + AParameters), @saSecurity,
@saSecurity, True, NORMAL_PRIORITY_CLASS, nil, nil, suiStartup, piProcess)
then
begin
repeat
dRunning := WaitForSingleObject(piProcess.hProcess, 100);
Application.ProcessMessages();
repeat
dRead := 0;
ReadFile(hRead, pBuffer[0], CReadBuffer, dRead, nil);
pBuffer[dRead] := #0;

OemToAnsi(pBuffer, pBuffer);
AMemo.Lines.Add(String(pBuffer));
until (dRead < CReadBuffer);
until (dRunning <> WAIT_TIMEOUT);
CloseHandle(piProcess.hProcess);
CloseHandle(piProcess.hThread);
end;

CloseHandle(hRead);
CloseHandle(hWrite);
end;
end;

Source: delphi.wikia.com

 

Publicité
Publicité
Commentaires
Publicité