2016-03-29 8 views
0

Wie überspringe ich eine nicht übereinstimmende Zeile in der Eingabe beim Ersetzen durch Regex?Autohotkey RegExReplace Unübertroffenes Muster überspringen

Für Ex. Unten ist der Inhalt meiner test.txt

[email protected] 
[email protected] 
elke engineering ltd.,@yahoo.com 
[email protected] 
[email protected] 

Unten ist mein Autohotkey Skript mit regex Code

ReplaceEmailsRegEx := "i)([a-z0-9]+(\.*|\_*|\-*))[email protected]([a-z][a-z0-9\-]+(\.|\-*\.))+[a-z]{2,6}" 
RemoveDuplicateCharactersRegEx := "s)(.)(?=.*\1)" 

Try{ 
FileRead, EmailFromTxtFile, test.txt 
OtherThanEmails :=RegExReplace(EmailFromTxtFile,ReplaceEmailsRegEx) 
Chars :=RegExReplace(OtherThanEmails,RemoveDuplicateCharactersRegEx) 
Loop{ 
StringReplace, OtherThanEmails, OtherThanEmails, `r`n`r`n,`r`n, UseErrorLevel 
If ErrorLevel = 0 
Break 
} 
If (StrLen(OtherThanEmails)){ 
Msgbox The Characters found other than email:`n%OtherThanEmails% 
} 
} 
catch e { 
ErrorString:="what: " . e.what . "file: " . e.file . " line: " . e.line . " msg: " . e.message . " extra: " . e.extra 
Msgbox An Exception was thrown`n%ErrorString% 
} 
Return 

Wenn es auf test.txt ersetzen wirft es Fehler:

e.what contains 'RegExReplace', e.line is 10 

Es führt ohne Fehler, wenn ich 3. E-Mail in test.txt entferne. Wie ändere ich meine Regex, um die problematische Zeichenfolge zu überspringen?

+0

Aus der Ausführung auf Fehler der gesamten Datei beendet. So überspringt die verbleibenden gültigen E-Mail-Übereinstimmungen – Dhay

+0

Für die Person, die downvoted: Kann ich den Grund wissen, so dass ich meine nächsten Beiträge verbessern kann, um nützlich zu sein. – Dhay

+1

Sie haben eine klassische katastrophale Backtracking mit Ihrer Regex. Woher hast du dieses Muster? Bitte versuchen Sie 'i) [a-z0-9] + (?: (?: \. + | _ + | - +) [a-z0-9] +) * @ ([az] [- a-z0- 9] + \.) + [Az] {2,6} '. Oder 'i) [a-z0-9] + (?: ([._-]) \ 1 * [a-z0-9] +) * @ ([az] [- a-z0-9] + \ .) + [az] {2,6} ' –

Antwort

1

Das Problem, das Sie haben, ist katastrophal Backtracking aufgrund der verschachtelten Quantifikator zu Beginn: ([a-z0-9]+(\.*|\_*|\-*))+. Hier sind die ., _ und - alle optional aufgrund der * Quantifizierer und damit wird Ihr Muster auf ([a-z0-9]+)+ reduziert.

I "Abrollen" das erste Teilmuster deuten darauf hin, es linear zu machen:

i)[a-z0-9]+(?:(?:\.+|_+|-+)[a-z0-9]+)*@([a-z][-a-z0-9]+\.)+[a-z]{2,6} 

Oder

i)[a-z0-9]+(?:([._-])\1*[a-z0-9]+)*@(?:[a-z][-a-z0-9]+\.)+[a-z]{2,6} 

Sie auch \1* entfernen, wenn Sie nicht mehr als 1 . oder _ erlauben oder - dazwischen "Worte".

Auch gibt es keine Notwendigkeit bei der Verwendung mit \-* Wechseln in (\.|\-*\.) ist, wie der Bindestrich mit der vorhergehenden Zeichenklasse übereinstimmt, so können diese Teilmuster zu \. reduziert werden.

Siehe regex demo