IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Validation d'une chaîne FEN par les expressions régulières


Sujet :

Delphi

  1. #1
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut Validation d'une chaîne FEN par les expressions régulières
    Bonjour !

    J'ai besoin de me fabriquer une fonction qui vérifie la validité d'une chaîne FEN. J'ai essayé de voir si je pourrais le faire avec des expressions régulières (l'unité RegularExpressions de Delphi XE2). J'aimerais bien avoir votre expertise sur ce que j'ai déjà fait.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    { Delphi XE2
      Essai d'un validateur de chaîne FEN
      http://kirill-kryukov.com/chess/doc/fen.html
    }
     
    program Validateur;
     
    {$APPTYPE CONSOLE}
     
    uses
      StrUtils, Types, RegularExpressions;
     
    const
      s: array[1..4]of string = (
        'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
        'rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2',
        'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2',
        '4k3/8/8/8/8/8/4P3/4K3 w - - 5 39'
      );
     
    var
      a: TStringDynArray;
      e: TRegEx;
      p: string;
     
    begin
      a := SplitString(s[4], ' ');
      Assert(Length(a) = 6);
     
      p := DupeString('[1-8BKNPQRbknpqr]+/', 7) + '[1-8BKNPQRbknpqr]+';
      e.Create(p);
      Assert(e.IsMatch(a[0]));
     
      e.Create('K');
      Assert(e.IsMatch(a[0]));
     
      e.Create('k');
      Assert(e.IsMatch(a[0]));
     
      e.Create('w|b');
      Assert(e.IsMatch(a[1]));
     
      e.Create('[KQkq]+|\-');
      Assert(e.IsMatch(a[2]));
     
      e.Create('[a-h][36]|\-');
      Assert(e.IsMatch(a[3]));
     
      //e.Create('[0-9]+');
      e.Create('\d+');
      Assert(e.IsMatch(a[4]));
      Assert(e.IsMatch(a[5]));
     
      Write('Appuyez sur la touche Entrée... ');
      ReadLn;
    end.
    Et pour commencer j'ai une question. Comment est-ce que je peux obtenir la chaîne correspondant au motif ? Par exemple, le code suivant me permet de savoir qu'il y a un "w" ou un "b" dans la chaîne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      e.Create('w|b');
      Assert(e.IsMatch(a[1]));
    Mais ça n'est pas suffisant : il faudrait vérifier que la chaîne n'est constituée de rien d'autre que d'un "w" ou d'un "b". Donc j'aurais voulu faire une vérification du genre Assert(e.ChaineCorrespondante(a[1]) = a[1]) mais je n'ai pas trouvé cette fonction.

    Merci d'avance !
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  2. #2
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    J'ai trouvé l'écriture que je cherchais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      e.Create('w|b');
      //Assert(e.IsMatch(a[1]));
      Assert(e.Match(a[1]).Value = a[1]);
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  3. #3
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    Je crois que j'ai fini mon programme. Il est possible qu'il contienne des erreurs, car c'est la première fois que j'utilise les expressions régulières.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    unit FEN_Validator;
     
    interface
     
    function IsFEN(const s: string): boolean;
     
    implementation
     
    uses
      StrUtils,
      Types,
      RegularExpressions,
      SysUtils,
      Character;
     
    function IsFEN(const s: string): boolean;
     
      function N(const s: string): integer;
      var
        i: integer;
      begin
        result := 0;
        for i := 1 to Length(s) do
          if IsLetter(s[i]) then
            Inc(result)
          else
            if IsDigit(s[i]) then
              Inc(result, StrToInt(s[i]));
      end;
     
    var
      a, b: TStringDynArray;
      e: TRegEx;
      i: integer;
     
    begin
      result := TRUE;
     
      a := SplitString(s, ' ');
      result := result and (Length(a) = 6);
      if not result then
        Exit;
     
      e.Create('K');
      result := result and (e.IsMatch(a[0]));
      if not result then
        Exit;
     
      e.Create('k');
      result := result and (e.IsMatch(a[0]));
      if not result then
        Exit;
     
      b := SplitString(a[0], '/');
      result := result and (Length(b) = 8);
      if not result then
        Exit;
     
      e.Create('[1-8BKNPQRbknpqr]+');
      for i := Low(b) to High(b) do
      begin
        result := result and (e.Match(b[i]).Value = b[i]) and (N(b[i]) = 8);
        if not result then
          Exit;
      end;
     
      e.Create('w|b');
      result := result and (e.Match(a[1]).Value = a[1]);
      if not result then
        Exit;
     
      e.Create('[KQkq]+|\-');
      result := result and (e.Match(a[2]).Value = a[2]);
      if not result then
        Exit;
     
      e.Create('[a-h][36]|\-');
      result := result and (e.Match(a[3]).Value = a[3]);
      if not result then
        Exit;
     
      e.Create('\d+');
      result := result and (e.Match(a[4]).Value = a[4]) and (StrToInt(a[4]) >= 0);
      if not result then
        Exit;
     
      result := result and (e.Match(a[5]).Value = a[5]) and (StrToInt(a[5]) >= 1);
      if not result then
        Exit;
    end;
     
    end.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    { Delphi XE2
      Essai d'un validateur de chaîne FEN
      http://kirill-kryukov.com/chess/doc/fen.html
    }
     
    program Test;
     
    {$APPTYPE CONSOLE}
     
    uses
      FEN_Validator in 'FEN_Validator.pas';
     
    const
      ss: array[1..4]of string = (
        'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
        'rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2',
        'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2',
        '4k3/8/8/8/8/8/4P3/4K3 w - - 5 39'
      );
     
    var
      i: integer;
     
    begin
      for i := Low(ss) to High(ss) do
        WriteLn(IsFEN(ss[i]));
     
      Write('Appuyez sur la touche Entrée... ');
      ReadLn;
    end.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  4. #4
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    En lisant de la documentation, je me suis aperçu qu'il n'était pas nécessaire de passer par une variable de type TRegEx et que je pouvais écrire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      //e.Create('K');
      //result := result and (e.IsMatch(a[0]));
      result := result and TRegEx.IsMatch(a[0], 'K');
    Du coup j'ai commencé à comprendre ce que veut dire "class function".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // http://docwiki.embarcadero.com/Libraries/XE2/fr/System.RegularExpressions.TRegEx
    TRegEx = record
      ...
      class function IsMatch(const Input, Pattern: string): Boolean; overload; static;
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  5. #5
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    Je déborde un peu de mon sujet initial mais comprenez-vous quelque chose à cet exemple ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    // http://docwiki.embarcadero.com/CodeExamples/XE2/en/TRegExReplace_(Delphi)
     
    var
      i: integer;
     
    function TForm1.ReplaceCC(const Match: TMatch): string;
    begin
      i := i + 1;
      Result := IntToStr(i);
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      r: TRegEx;
      s: string;
      e: TMatchEvaluator;
    begin
      i := 0;
      s := Edit1.Text; // aabbccddeeffcccgghhcccciijjcccckkcc
      r.Create('cc');
      e := ReplaceCC;
      Edit2.Text := r.Replace(s, e); // aabb1ddeeff2cgghh34iijj56kk7
    end;
    Personnellement, j'ai beau le relire : je n'y comprends toujours rien. Je vois bien ce que ça fait, mais la logique du code m'échappe.

    P.-S. J'ai trouvé la déclaration du type TMatchEvaluator. C'est trop fort pour moi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TMatchEvaluator = function(const Match: TMatch): string of object;
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  6. #6
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Roland Chastain Voir le message
    J'ai trouvé l'écriture que je cherchais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      e.Create('w|b');
      //Assert(e.IsMatch(a[1]));
      Assert(e.Match(a[1]).Value = a[1]);
    En fait il n'est pas nécessaire de faire cette comparaison. Il suffit d'utiliser les caractères "^" et "$" qui signifient respectivement le début et la fin de la chaîne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      WriteLn(TRegex.IsMatch('Xw', '^[wb]$')); // FALSE
      WriteLn(TRegex.IsMatch('wX', '^[wb]$')); // FALSE
      WriteLn(TRegex.IsMatch('w', '^[wb]$')); // TRUE
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  7. #7
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    Un deuxième exemple d'emploi de TMatchEvaluator : ça commence à rentrer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    unit U51;
     
    interface
     
    uses
      Winapi.Windows,
      Winapi.Messages,
      System.SysUtils,
      System.Variants,
      System.Classes,
     
      System.RegularExpressions,
     
      Vcl.Graphics,
      Vcl.Controls,
      Vcl.Forms,
      Vcl.Dialogs,
      Vcl.StdCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
     
        Memo1: TMemo;    procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
        function MyReplace(const Match: TMatch): string;
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    (* http://www.delphi-treff.de/tutorials/objectpascal/regulaere-ausdruecke-in-delphi/ *)
     
    const
      input = 'Date et heure actuelles : 29/09/2014 23:54:43';
      regex = '\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}';
     
    procedure TForm1.Button1Click(sender: TObject);
    var
      myEval: TMatchEvaluator;
    begin
      myEval := MyReplace;
      Memo1.Lines.Add(TRegEx.Replace(input, regex, myEval));
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Memo1.Lines.Add(input);
    end;
     
    function TForm1.MyReplace(const match: TMatch): string;
    begin
      Result := DateTimeToStr(Now);
     
      with match do
        ShowMessage(Format('match.Value=[%s] match.Index=[%d]', [Value, Index]));
    end;
     
    end.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  8. #8
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    Il est à noter que si on utilise, au lieu de l'unité RegularExpressions, l'unité RegularExpressionsCore, alors le même code peut être compilé tel quel avec les versions plus anciennes de Delphi et l'unité PerlRegex.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    (* Testé avec Delphi 7 et avec Delphi XE2. *)
     
    uses
    {$IFDEF VER230}
      RegularExpressionsCore;
    {$ELSE}
      PerlRegex; // http://www.regular-expressions.info/download/TPerlRegEx.zip
    {$ENDIF}
     
    function IsMatch(const aSubject, aRegex: string): boolean;
    begin
      with TPerlRegex.Create do
      begin
        Subject := utf8string(aSubject);
        Regex := utf8string(aRegex);
        result := Match;
        Free;
      end;
    end;
     
    begin
      WriteLn(IsMatch('w', '^[wb]$'));  // TRUE
      WriteLn(IsMatch('b', '^[wb]$'));  // TRUE
      WriteLn(IsMatch('Xb', '^[wb]$')); // FALSE
      WriteLn(IsMatch('bX', '^[wb]$')); // FALSE
      ReadLn;
    end.
    Extrait du fichier README.txt inclus dans l'archive TPerlRegex.zip :

    This version of TPerlRegEx is compatible with the TPerlRegEx class in the RegularExpressionsCore unit in Delphi XE.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  9. #9
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    J'ai fait une petite application pour pouvoir commodément m'exercer aux expressions régulières. Au lancement du programme, le contenu d'un fichier (chemin à modifier dans le code) est chargé dans un TMemo. Dans un TEdit on tape une expression régulière. En appuyant sur le bouton, on obtient toutes les correspondances de l'expression avec le contenu du fichier

    Personnellement j'ai mis comme fichier le DFM du projet. Critique et suggestions bienvenues.
    Images attachées Images attachées  
    Fichiers attachés Fichiers attachés
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  10. #10
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    Retour au problème initial. Voici une nouvelle version du validateur, qui se compile avec Delphi 7 et avec Delphi XE2 (voir explication plus haut dans la discussion).

    Les expressions régulières ont été revues.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
     
    unit FEN_Validator;
     
    interface
     
    function IsFEN(const s: string): boolean;
     
    implementation
     
    uses
      Classes,
    {$IF CompilerVersion >= 22.0}
      SysUtils,
      RegularExpressionsCore;
    {$ELSE}
      PerlRegex; (* http://www.regular-expressions.info/download/TPerlRegEx.zip *)
    {$IFEND}
     
    function N(const s: string): integer;
    var
      i: integer;
    begin
      result := 0;
      for i := 1 to Length(s) do
        {$IF CompilerVersion >= 22.0}
        if CharInSet(s[i], ['A'..'Z', 'a'..'z']) then
        {$ELSE}
        if s[i] in ['A'..'Z', 'a'..'z'] then
        {$IFEND}
          Inc(result)
        else
          {$IF CompilerVersion >= 22.0}
          if CharInSet(s[i], ['1'..'8']) then
          {$ELSE}
          if s[i] in ['1'..'8'] then
          {$IFEND}
            Inc(result, Ord(s[i]) - Ord('0'));
    end;
     
    function IsFEN(const s: string): boolean;
    var
      r: TPerlRegex;
      a, b: TStrings;
      i: integer;
    begin
      r := TPerlRegex.Create;
      a := TStringList.Create;
      b := TStringList.Create;
     
      result := TRUE;
     
      r.Subject := utf8string(s);
      r.Regex := '\s';
      r.Split(a, 0);
      result := result and (a.Count = 6);
     
      r.Subject := utf8string(a[0]);
      r.Regex := '/';
      r.Split(b, 0);
      result := result and (b.Count = 8);
     
      r.Regex := 'K';
      result := result and r.Match and not r.MatchAgain;
     
      r.Regex := 'k';
      result := result and r.Match and not r.MatchAgain;
     
      r.Regex := '^[1-8BKNPQRbknpqr]+$';
      for i := 0 to b.Count - 1 do
      begin
        r.Subject := utf8string(b[i]);
        result := result and r.Match and (N(b[i]) = 8);
      end;
     
      r.Subject := utf8string(a[1]);
      r.RegEx := '^[wb]$';
      result := result and r.Match;
     
      r.Subject := utf8string(a[2]);
      r.RegEx := '^[KQkq]+$|^\-$';
      result := result and r.Match;
     
      r.Subject := utf8string(a[3]);
      r.RegEx := '^[a-h][36]$|^\-$';
      result := result and r.Match;
     
      r.Subject := utf8string(a[4]);
      r.RegEx := '^\d+$';
      result := result and r.Match;
     
      r.Subject := utf8string(a[5]);
      r.RegEx := '^[1-9]\d*$';
      result := result and r.Match;
     
      r.Free;
      a.Free;
      b.Free;
    end;
     
    end.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    program Test;
    {$APPTYPE CONSOLE}
     
    uses
      FEN_Validator;
     
    const
      sample: array[1..4]of string = (
        'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
        'rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2',
        'rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2',
        '4k3/8/8/8/8/8/4P3/4K3 w - - 5 39'
      );
     
    var
      i: integer;
     
    begin
      for i := Low(sample) to High(sample) do
        Assert(IsFEN(sample[i]));
     
      Write('FIN');
      ReadLn;
    end.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  11. #11
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 062
    Points : 15 353
    Points
    15 353
    Billets dans le blog
    9
    Par défaut
    Le validateur de chaînes FEN est devenu une librairie dynamique (mais on peut toujours utiliser directement l'unité).

    J'ai ajouté des chaînes invalides dans l'échantillon : elles sont correctement détectées.

    Au-delà de l'utilité (très relative) de ce programme, j'ai trouvé que ce sujet convenait bien à un exercice sur les expressions régulières. Je n'ai pas pris le temps de commenter mes expressions régulières une à une, 1° parce que je n'étais pas sûr qu'elles soient bonnes (j'en ai d'ailleurs modifié plusieurs en cours de route), 2° parce que je ne sais pas si cela aurait intéressé quelqu'un.

    P.-S. Je suis tombé sur une page où quelqu'un propose une expression unique pour valider toute la chaîne d'un seul coup ! Je vous laisse apprécier.

    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    \s*([rnbqkpRNBQKP1-8]+\/){7}([rnbqkpRNBQKP1-8]+)\s[bw-]\s(([a-hkqA-HKQ]{1,4})|(-))\s(([a-h][36])|(-))\s\d+\s\d+\s*
    Fichiers attachés Fichiers attachés
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Validation d'une chaîne au format FEN
    Par Roland Chastain dans le forum Lua
    Réponses: 7
    Dernier message: 01/11/2014, 16h27
  2. [Free Pascal] Validateur de chaîne FEN utilisant les expressions régulières
    Par Roland Chastain dans le forum Codes sources à télécharger
    Réponses: 0
    Dernier message: 03/10/2014, 11h40
  3. Réponses: 3
    Dernier message: 28/07/2014, 02h48
  4. Vérifier qu'une chaîne commence par
    Par BenoitDenis dans le forum Langage
    Réponses: 5
    Dernier message: 02/05/2006, 13h00
  5. rendre une page invisible par les mteurs de recherche
    Par Delphi-ne dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 01/04/2006, 20h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo