TPerlRegEx Delphi – wyciąganie tekstu od słowa ala do bela, leniwe dopasowanie

Pytanie

TPerlRegEx Delphi, wyszukiwanie od słowa ala do słowa bela reszta pomijana

Odpowiedź Sztucznej Inteligencji


Bezpośrednia odpowiedź na pytanie

  • Najprościej: użyj wzorca z „leniwyą” kropką i granicami słów: \bala\b([\s\S]*?)\bbela\b
  • W TPerlRegEx:
    • RegEx := '\bala\b([\s\S]*?)\bbela\b';
    • Subject := Tekst;
    • Options: [preCaseLess] (opcjonalnie), [preSingleLine] gdy chcesz użyć kropki „.” zamiast [\s\S]
  • Wynik między słowami masz w Groups[1]; całe „od ala do bela” w MatchedText.

Szczegółowa analiza problemu

  • Cel: wydobyć (i ewentualnie jedynie zostawić) fragment zaczynający się na słowo „ala” i kończący na słowo „bela”, pomijając resztę.
  • Teoria:
    • „Leniwość” (quantifier ?): .? lub [\s\S]*? zatrzymuje się na najbliższym kolejnym dopasowaniu „bela”, zamiast pożerać aż do ostatniego „bela”.
    • Granice słowa \b: gwarantują, że nie trafisz w „kalafior” (z „ala”) ani „tabela” (z „bela”).
    • Nowe linie: „.” domyślnie nie obejmuje CR/LF; dwie równoważne drogi:
      • Wzorzec z [\s\S]*? (działa bez zmiany opcji).
      • Albo „.” + preSingleLine (DOTALL).
  • Praktyka (TPerlRegEx – System.RegularExpressionsCore/RegularExpressionsCore, zależnie od wersji Delphi):
    • Pojedyncze dopasowanie i pobranie środka:
      uses System.RegularExpressionsCore;
      var R: TPerlRegEx;
      begin
        R := TPerlRegEx.Create;
        try
          R.RegEx   := '\bala\b([\s\S]*?)\bbela\b';
          R.Subject := InputText;
          // R.Options := [preSingleLine]; // gdy używasz „ala.*?bela”
          if R.Match then
            ShowMessage('Między: ' + R.Groups[1])    // tylko wnętrze
          else
            ShowMessage('Brak dopasowania');
        finally
          R.Free;
        end;
      end;
    • Wszystkie wystąpienia (iteracja):
      if R.Match then
        repeat
          Memo1.Lines.Add(R.Groups[1]);  // wnętrze
        until not R.MatchAgain;
    • Zatrzymanie słów w wyniku (włącznie z „ala” i „bela”): użyj grupowania całego fragmentu:
      • Wzorzec: (\bala\b[\s\S]*?\bbela\b)
      • Wtedy R.Groups[1] zawiera cały fragment wraz z „ala” i „bela”.
    • „Zachłanne” dopasowanie (od pierwszego „ala” do ostatniego „bela”): \bala\b[\s\S]*\bbela\b (bez „?”). Zwykle niepożądane tutaj.

Aktualne informacje i trendy

  • Nowe Delphi (XE+ … 12.x) dostarcza dwa API:
    • TPerlRegEx (System.RegularExpressionsCore): PCRE-owy silnik, klasyczne właściwości (Subject, RegEx, Options, Groups[], MatchAgain).
    • TRegEx (System.RegularExpressions): record-API; analogiczne wzorce, opcje roSingleLine/roIgnoreCase; jeśli nie potrzebujesz TPerlRegEx, TRegEx bywa prostszy w użyciu.
  • Rekomendacja projektowa: jeśli nie masz zależności historycznych od TPerlRegEx, rozważ TRegEx.Matches dla czytelności i prostego zarządzania pamięcią.

Wspierające wyjaśnienia i detale

  • Warianty wzorca:
    • Tylko całe słowa i ignorowanie wielkości: (?i)\bala\b([\s\S]*?)\bbela\b lub Options: [preCaseLess].
    • Bez nowych linii: \bala\b(.*?)\bbela\b i Options bez preSingleLine.
    • Dodatkowe białe znaki przy brzegach: \bala\b\s([\s\S]?)\s*\bbela\b
  • Różnice „.” vs [\s\S]:
    • „.” + preSingleLine jest czytelne.
    • [\s\S] jest niezależne od opcji (przenośne między silnikami).
  • Wydajność:
    • Leniwe .*? przy bardzo długich fragmentach bez „bela” przeskanuje koniec tekstu – to normalne.
    • Możesz zastosować „temperowaną kropkę” dla redukcji backtrackingu: \bala\b(?:(?!\bbela\b)[\s\S])*?\bbela\b

Aspekty etyczne i prawne

  • Korzystając z bibliotek zewnętrznych (gdybyś użył alternatyw typu TRegExpr), sprawdź licencję. TPerlRegEx/TRegEx dostarczane z Delphi są bezpieczne licencyjnie w ramach licencji RAD Studio.

Praktyczne wskazówki

  • Jeśli chcesz „zostawić tylko fragment, resztę wyciąć”, najprościej:
    • if R.Match then Output := R.MatchedText else Output := '';
  • W TRegEx (alternatywa):
    uses System.RegularExpressions;
    var M := TRegEx.Match(InputText, '\bala\b([\s\S]*?)\bbela\b',
                          [roIgnoreCase, roSingleLine]);
    if M.Success then
      Output := M.Value;     // cały fragment od ala do bela
  • Testuj dane skrajne:
    • Brak „bela”, wielokrotne „ala/bela”, nowe linie, „Ala”/„BELA”, wystąpienia w środku innych słów.

Ewentualne zastrzeżenia lub uwagi dodatkowe

  • \b i Unicode: w typowych ustawieniach działa poprawnie, ale dla tekstów silnie diakrytyzowanych sprawdź, czy granice słów odpowiadają Twoim oczekiwaniom (silnik PCRE z ustawieniami Delphi zwykle to obsługuje prawidłowo).
  • Ogromne pliki: rozważ strumieniowe przetwarzanie lub bardziej specyficzne wzorce, by skrócić skanowanie.

Sugestie dalszych badań

  • Dokumentacja System.RegularExpressionsCore.TPerlRegEx i System.RegularExpressions.TRegEx (RAD Studio DocWiki).
  • Poradniki PCRE nt. leniwych/zachłannych kwantyfikatorów i granic słów.
  • Narzędzia do interaktywnego testowania regex (np. RegexBuddy) z profilem „Delphi/PCRE”.

Krótkie podsumowanie

  • Użyj: \bala\b([\s\S]*?)\bbela\b z TPerlRegEx.
  • Groups[1] to „między ala i bela”, MatchedText to cały fragment wraz z granicznymi słowami.
  • Dla nowych linii: [\s\S]*? lub preSingleLine; dla „Ala”/„BELA”: preCaseLess.
  • Iterację po wielu dopasowaniach załatwia MatchAgain. Jeśli podasz konkretny przykład wejścia/oczekiwań, doprecyzuję wzorzec i kod.

Oceń odpowiedź:
Zastrzeżenie: Odpowiedzi udzielone przez sztuczną inteligencję (model językowy) mogą być niedokładne i wprowadzające w błąd. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi powinny być zweryfikowane przez użytkownika.

Zadaj dodatkowe pytanie Sztucznej Inteligencji

Czekaj (2min)...