PowerShell RegEx

sikarr

Lt. Commander
Dabei seit
Mai 2010
Beiträge
1.681
Hi Leute,

irgendwie hab ich nen Knoten im Kopf.

Ich will/muss/darf/soll einen Wert prüfen der von einer OCR kommt, ist eigentlich total simple und funktioniert super bis auf eine Ausnahme.

Der Wert den ich prüfe ist eine 7 stellige Zahl, hier soll einfach nur geprüft werden ob der String auch wirklich nur diese 7 stellige Zahl enthält. Funktioniert, ganz Simpel.

Jetzt ist heute durch Zufall aufgefallen das wenn am Ende dieses Strings ein Leerzeichen ist die Prüfung die Zahl durch winkt.
Probiert habe ich "\d{7}" und auch "[0-9]{7}" mit und ohne "\b" und "^$". in einer einfachen IF ELSE Schleife, hilft alles nix wenn am Ende ein Leerzeichen steht.

Weis jemand Rat? ist bestimmt total banal aber ich sehs einfach nicht.:confused_alt::freak::D
 

teufelernie

Lt. Commander
Dabei seit
Sep. 2004
Beiträge
1.803
Erm keine Ahnung von powershell, aber regex ist eigentlich überall gleich.
Nutze er das cheat-sheet hier und teste er dort seinen Code: https://pythex.org
 

Yuuri

Fleet Admiral
Dabei seit
Okt. 2010
Beiträge
12.695
Mach doch vorher ein .Trim() oder was hält dich davon ab? Das entfernt jeglichen Whitespace am Anfang und Ende.
Code:
if( $string.ToString().Trim() -match "^\d{7}$" )
{
  # ...
}
Ansonsten: ^\s*\d{7}\s*$ - [<Whitespace>]<Zahl mit 7 Ziffern>[<Whitespace>]

PS: Es gibt keine If-Schleifen!!!
 

sikarr

Lt. Commander
Ersteller dieses Themas
Dabei seit
Mai 2010
Beiträge
1.681
Trim wäre eine Möglichkeit, aber ich möchte ja wissen wenn die Prüfung negativ ausfällt, durchlaufen tut es auch so, es generiert dann halt bloss einen Hinweis für weitere arbeiten.

PS: Du hast natürlich Recht!!!
 

Exterior

Lt. Junior Grade
Dabei seit
Nov. 2012
Beiträge
259
Zeig doch einfach mal den genauen RegEx, den du verwendest. Denn eigentlich sollte "/^\d{7}$/" funktionieren.

Oder poste mal das Script dafür.
 

sikarr

Lt. Commander
Ersteller dieses Themas
Dabei seit
Mai 2010
Beiträge
1.681
Kann ich erst morgen, ist auf Arbeit, aber ich habe eigentlich alle Kombinationen oben aufgelistet.

Ich möchte eigentlich nur einen Treffer wenn mehr oder weniger als diese 7 stellige Zahl drinn steht.
Die Zahl ändert sich auch laufend, sind Sendungsnummern einer Spedition, da gibts kein Schema.

Manchmal kann der Wert der drinn steht ja sogar stimmen, deswegen nur der Hinweis und kein Abbruch oder Trim, damit man nachschauen kann.
 

BeBur

Lieutenant
Dabei seit
Nov. 2018
Beiträge
955
/^\d{7}$/ sollte eigentlich funktionieren, kleiner Test ergibt das auch.
Beim nächsten mal direkt schreiben, welche regexp ganz genau du ausprobiert hast.
 

pizza4ever

Lt. Commander
Dabei seit
Apr. 2009
Beiträge
1.557
Kannst du den Code mal Posten und ein Beispiel? Dann schaue ichs mir morgen an.

Empfehle dir allgemein den Absprung an der Stelle ins .net Framework, da du dort bessere RegEx Pattern Tester hast.
 

sikarr

Lt. Commander
Ersteller dieses Themas
Dabei seit
Mai 2010
Beiträge
1.681
Moin, an alle erstmal ein Danke.

@Exterior und @BeBur hatten Recht mit "^\d{7}$" obwohl ich dachte dieses auch probiert zu haben. Gerade nachgeschaut hatte ich noch "([0-9]{7})" drin stehen, warum das damit nicht klappte ist mir klar.

Gerade noch einen anderen anderen Fehler gefunden der meine Hinweismeldung unterdrückte.
PowerShell:
switch ($niederlassung){
Mochau    {$lspattern = '^\d{7}$'; $rkpattern = '^\d{6}$'; BREAK}
DD        {$lspattern = '^\d{7}$'; $rkpattern = '^\d{6}$'; BREAK}
Erfurt    {$lspattern = '^\d{6}$'; $rkpattern = '^\d{5}$'; BREAK}
Fern    {$lspattern = '^\d{6}$'; $rkpattern = '^\d{5}$'; BREAK}
}

$lsliste = Get-ChildItem -Path $ilspfad -Recurse -Include "*.txt"

$lsfehler = @()

foreach ($lsls in $lsliste){
    $lsls = Import-Csv -Path $lsls -Delimiter ";" -Header "sendungsnummer","platzhalter"
    IF ($lsls.sendungsnummer -notmatch $lspattern) {
        $lsfehler += $lsls.sendungsnummer
        }
}
Damit klappts nun.
 
Zuletzt bearbeitet:

pizza4ever

Lt. Commander
Dabei seit
Apr. 2009
Beiträge
1.557
Gut, empfehle dir wie gesagt bei sowas das .net Framework, damit kannst du im powershell z.b. hier

http://regexstorm.net/tester

deine expressions testen.

Codebeispiel:

$regex_pattern = '["][@][@][T][R][M][M][@][@][0]*'
$regex_replace = '"'

$line = [regex]::Replace($line,$regex_pattern,$regex_replace)
 

pizza4ever

Lt. Commander
Dabei seit
Apr. 2009
Beiträge
1.557
Naja, ein Regex was den Ausdruck

"@@TRIMM@@0 (das I wurde wohl irgendwo geschluckt) sucht und ihn abschneidet

1.) Finde ich regex in powershell deutlich müßiger als im nativen .net, es gibt einfach viel mehr doku und Codebeispiele. Ich hatte muir das vor 2 Jahren mal intensiver angeschaut und damals Probleme mit dem (nativen) Regex Powershell gehabt, und habs damals alles auf die .net Komponente umgeschrieben und seitdem keine Probleme gehabt.
2.) (aber das ist nun was allgemeines) macht es durchaus Sinn sich mal anzuschauen wie man das .net Framework im Powershell anspricht. Es bietet ungleich mehr Möglichkeiten bei teilweise deutlich höherer Performance. Wenn man schnell mal was machen will ist Powershell super, aber es hat halt auch grenzen.
 

Yuuri

Fleet Admiral
Dabei seit
Okt. 2010
Beiträge
12.695
Was ist am PowerShell Regex anders? Ist nichts Anderes als das, was im .NET Framework Verwendung findet, von den sprachlichen Konstrukten einer Scriptsprache mal abgesehen... Ich weiß aber auch nicht so recht was dein TRIMM Beispiel darstellen soll, vor allem nicht die zu tausenden, überflüssigen Klammern.
 

pizza4ever

Lt. Commander
Dabei seit
Apr. 2009
Beiträge
1.557
Nein, es ist nicht gleich
Code:
"Book" -match "BOok" ist true

"Book" -match "[B][O][o][k]" ist true

$match = "[B][O][o][k]" 
bzw $match = BOok"

und danach [regex]::Match("Book",$match) ist aber false
.. das ist Verbindung mit einem Tester kann natürlich zu unerwarteten Ergebnissen führen.
 
Zuletzt bearbeitet:

sikarr

Lt. Commander
Ersteller dieses Themas
Dabei seit
Mai 2010
Beiträge
1.681
PowerShell:
"Book" -cmatch "BOok" ist false
In dem fall würde ich -cmatch nehmen oder -eq
 

pizza4ever

Lt. Commander
Dabei seit
Apr. 2009
Beiträge
1.557
Ja, gibt sicher Möglichkeiten das zu handeln. Ich bin damals einfach besser mit der Kombi .net Regex und dem .net Tester gefahen, weil man alles schön testen kann (und ich eben Probleme hatten weil die Ausdrücke [teilweise] [minimal] abweichen).
 

BeBur

Lieutenant
Dabei seit
Nov. 2018
Beiträge
955
"-match" macht dann anscheinend schlicht kein regexp matching, sondern irgendwas anderes. Falls das so wie du es angibst korrekt ist. Muss man dann in der Doku nachschlagen, wenn man es verwenden will.

"[regex]::Match("Book",$match)" weist vom Namen her darauf hin, dass es übliches regexp matching ist und korrekterweise wird da auch false ausgegeben.

Siehe hier:
https://kevinmarquette.github.io/2017-07-31-Powershell-regex-regular-expression/#-match
-imatch makes it explicit that you are doing a case insensitive operation (the default)
Zugegebenermaßen schon ziemlicher Blödsinn mit dem man ggf. nicht rechnet. Vor allem wenn Menschen irreführenderweise Dinge schreiben wie:
The -match opperator takes a regular expression and returns $true if the pattern matches.
 
Zuletzt bearbeitet:

pizza4ever

Lt. Commander
Dabei seit
Apr. 2009
Beiträge
1.557
Es war vor deinem Edit ;)

Mal Bezug auf deinen Beitrag:

"Zugegebenermaßen schon ziemlicher Blödsinn mit dem man ggf. nicht rechnet. Vor allem wenn Menschen irreführenderweise Dinge schreiben wie[...]"

Ich hatte damals ein paar so Fallstricke und daher kommt meien Empfehlung. Ob man dieser folgt, blebt ja jedem selbst überlassen.
 
Top