Nichtnumerische Zeichen mit regulären Ausdrücken entfernen

Themen rund um den praktischen Einsatz von Firebird. Fragen zu SQL, Performance, Datenbankstrukturen, etc.

Moderator: thorben.braun

Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Hallo zusammen,

ich möchte aus einem Werte alle nichtnumerischen Zeichen entfernen. Es sollen also nur Zahlen übrigbleiben. Dies geht sicherlich mit regulären Ausdrücken. Vielleicht ist ja ein "Experte" diesbezüglich unter euch - ich bin es jedenfalls nicht. ;)

So mache ich das bislang:
-- Ausgangswert: +49.511 1234 567
-- Zielwert: 4951112234567

REPLACE(REPLACE(REPLACE('+49.511 1234 567', ' ', ''), '-', ''), '+', '')
Das geht sicherlich schöner mit regulären Ausdrücken.

Dank und Gruß
Martin
Martin Köditz
it & synergy GmbH
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Ich finde nun keinen RegEx im SQL von Firebird.
Aber wenn du Regex per Code aufrufen kannst und es eine Replace-Funktion gibt, kannst du
"[^[:digit:]]"
mit einer leeren Zeichenfolge ersetzen.
Es klappt auch (nicht Zahl)
"[^1234567890]"
Zuletzt geändert von bfuerchau am Mo 30. Nov 2020, 12:38, insgesamt 1-mal geändert.
Gerd
Beiträge: 234
Registriert: Di 1. Okt 2019, 17:13

Hallo Martin.

Ja, RegEx, würde das leisten.

Ich habe da aber noch etwas, was Dir vielleicht auch (weiter)helfen könnte:

Du bist doch in PHP 'unterwegs' ...
Es soll diese Library für PHP geben: libphonenumber-for-php
Auf GitHub.

Deren Möglichkeiten kann man zunächst gleich einmal online checken.
So findet sich ganz unten auf der Webseite auch ein Link, welcher zu eben dieser Online-Demo führt. Habe es mit wenigen Nummern geprüft. Bringt jeweils eine erwartungsgemäße (korrekte) Formatierung der Telefonnummer bzw. Meldung.



Mein Input-Beispiel:
0049 / 030 - 123456 45 Schulze

Format Wert
E164: Invalid Number
National: Invalid Number
International: Invalid Number
RFC3966: Invalid Number


Mein Input-Beispiel:
0049 / 030 - 123456 45

Format Wert
E164: +493012345645
National: 030 12345645
International: +49 30 12345645
RFC3966: tel:+49-30-12345645



Viele Grüße
Gerd
Linux Mint 21.3 Virginia Cinnamon 6.0.4
Firebird 5.0.0., Embedded, ISQL: LI-V5.0.0.1306
Lazarus 3.0.0 - FPC 3.2.2
Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Hallo Gerd,

danke für den Link. Das hilft mir bei meiner Abfrage zunächst nicht, ist aber für andere Zwecke durchaus interessant.

Gruß
Martin
Martin Köditz
it & synergy GmbH
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Du könntest dir RegEx-Funktionen auch selber schreiben oder schreiben lassen:
https://www.tabsoverspaces.com/233625-g ... ird-in-net

Das soll auch ab FB 3.0 schon klappen.
zappa2
Beiträge: 31
Registriert: Fr 5. Okt 2018, 10:59

Ich würde es mit einer kleinen Hilfsfunktion erledigen, die nur noch Zifferzeichen in einer Zeichenkette behält:

Code: Alles auswählen

create or alter function STR2INT (
    I_S varchar(255))
returns varchar(55)
as
declare variable VI integer;
declare variable VS varchar(55);
declare variable VC char(1);
begin
  vi = 1;                                         -- Zählervariable
  vs = '';                                        -- Ergebnisstring
  while ( vi <= char_length(:i_s) ) do begin      -- Zeichen ..
    vc = substring(:i_s from :vi for 1);             -- .. für Zeichen
    if (:vc between '0' and '9') then vs=:vs||:vc;   -- Ziffer? => dann anhängen
    vi = :vi + 1;                                    -- Zähler inkrementieren
  end
  return :vs;                                     -- Ergebnisstring
end
Das hat mit regulären Ausdrücken natürlich absolut nix zu tun. Antwort geht dementsprechend wohl an der Frage vorbei. Sorry :roll:
Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Hallo zappa2,

ich hatte schon befürchtet, dass es auf eine benutzerdefinierte Funktion hinauslaufen wird. Das ist nicht weiter tragisch. Ich hatte nur gehofft, dass es bereits eine andere Art der Implementierung hierzu gibt.

Mittels SIMILAR TO können ja auch reguläre Ausdrücke in Substring() verwendet werden. Dies hilft mir jedoch in dieser Situation nicht.

Aus der Sprachrefernz entnommen:
SIMILAR TO findet eine Zeichenkette anhand eines Regulären Ausdruck-Musters in SQL (engl. SQL Regular Expression Pattern). Anders als in einigen anderen Sprachen muss das Muster mit der gesamten Zeichenkette übereinstimmen, um erfolgreich zu sein — die Übereinstimmung eines Teilstrings reicht nicht aus. Ist ein Operand NULL, ist auch das Ergebnis NULL. Andernfalls ist das Ergebnis TRUE oder FALSE.
Quelle: https://firebirdsql.org/file/documentat ... mppreds-de

Aber ich danke dir für den Quellcode. Ich werde das mal testen.

Gruß
Martin
Martin Köditz
it & synergy GmbH
vr2
Beiträge: 214
Registriert: Fr 13. Apr 2018, 00:13

Hallo Martin, alle,

habe entlang Deiner Frage auch etwas geforscht, aber die substring-Funktion zusammen mit similar to reichte nicht. Sie extrahiert offensichtlich keine unzusammenhängenden Gruppen von Ziffern aus einem String, jedenfalls wüssste ich nicht wie. Gruppenbildung mit runden Klammern? Die Doku dazu (im Firebird 3 Installationsverzeichnis, im Netz gar keine Erwähnung) ist sehr dünn.

Von daher ist der Ansatz mit Stored Function schon der bessere.

Grüße, Volker
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Similar entspricht ja nur, durch RegEx, einem erweiterten "LIke".
Damit kann man also nur feststellen, ob der gesuchte Ausdruck enthalten ist.

Anscheinend hat sich noch keiner wirklich damit beschäftigt und entsprechende Funktionen ins Netz gestellt.
Die Projekte, die ich finde, sind z.T. von FB 1.0 (2003) oder hören 2010 auf.
vr2
Beiträge: 214
Registriert: Fr 13. Apr 2018, 00:13

bfuerchau hat geschrieben: Mi 2. Dez 2020, 09:44 Similar entspricht ja nur, durch RegEx, einem erweiterten "LIke".
Damit kann man also nur feststellen, ob der gesuchte Ausdruck enthalten ist.
ich habe doch von substring mit similar gesprochen. Damit kann man einen Teilstring extrahieren.
bfuerchau hat geschrieben: Mi 2. Dez 2020, 09:44 Anscheinend hat sich noch keiner wirklich damit beschäftigt und entsprechende Funktionen ins Netz gestellt.
Die Projekte, die ich finde, sind z.T. von FB 1.0 (2003) oder hören 2010 auf.
auch das hab ich erwähnt, steht im Firebird 3 Installationsverzeichnis, genauer gesagt in \doc\sql.extensions\README.substring_similar.txt und ist von Mai 2013. Darin finden sich die folgenden Beispiele und darüber etwas Syntaxdefinition. Diese Art von substring-Verwendung geht schon in die Richtung, die Martin braucht (Inhalt aus einem String mit bekanntem Format extrahieren, zb Telefonnr).

Code: Alles auswählen

substring('abcabc' similar 'a#"bcab#"c' escape '#')  -- bcab
substring('abcabc' similar 'a#"%#"c' escape '#')     -- bcab
substring('abcabc' similar '_#"%#"_' escape '#')     -- bcab
substring('abcabc' similar '#"(abc)*#"' escape '#')  -- abcabc
substring('abcabc' similar '#"abc#"' escape '#')     -- <null>
Meine Tests waren u.a. die folgenden. Aber zu mehr als mir den ersten Zahlenbereich der Telnr ins Ergebnis extrahieren konnte ich meine Test-Expressions nicht bewegen. Dazu sagt die Doku zu wenig.

Code: Alles auswählen

select substring('abcabc' similar 'a#"bcab#"c' escape '#') xx,
substring('abc123abc456' similar 'abc#"[0-9]*#"abc' escape '#') num,
substring('abc123abc456' similar '%#"[0-9]+#"%' escape '#') num2,
substring('+49.511 1234 567' similar '#+?#"[0-9]+#"%' escape '#') num3,
substring('+49.511 1234 567' similar '#+?#"[0-9]+_[0-9]+#"%' escape '#') num4
from rdb$database
Wem das weiterhilft, der kann ja gerne weitere Erkenntnisse hier reinstellen. Ich hatte keine Lust mehr, rumzuprobieren.

Grüße, Volker
Antworten