2009-07-08 13 views
0

Ich habe ein Problem beim Schreiben eines regulären Ausdrucks. Wie könnte ich schreiben folgend:Eine String-Match-Anforderung in einen regulären Ausdruck umwandeln

  1. Start mit einer optionalen Zugriffsebene (eine Ziffer von 1 bis 5)
  2. gefolgt von einem Leerzeichen
  3. dann Name eines Benutzers zwischen 3 und 5 kleinen Buchstaben bestehend
  4. gefolgt von zwischen 3 und 5 Ziffern
  5. dann einem oder mehr Leerzeichen
  6. und dann einer vierstellige PIN-Nummer
  7. dann einem oder mehr Leerzeichen
  8. und derselbe Stift wieder zur Bestätigung ..

Wenn die Information gültig ist, eine Warnung, sagen: „Danke.“ Sonst "Die eingegebenen Informationen sind falsch."

schrieb ich die folgende, aber es nicht richtig funktioniert:

reg=/^(\d{1,5})?/s ([a-z]{3,5}\b\d{3,5}\s) \s\1 $/; 

ich Hilfe schätzen würde.

+2

wäre es hilfreich, wenn Sie ein paar Beispiele gegeben hätten. das wäre einfacher zu verstehen und dann lesen Sie Ihre Beschreibung – mkoryak

+1

ACK! Regulären Ausdruck! Renn weg! Renn weg! http://xkcd.com/208/ – bgw

+0

Ist das Hausaufgaben? – seth

Antwort

0

versuchen Sie dies: ([1-5])?\s[a-z]{3,5}(\s*\d{4}){2}

+1

Der Eingang muss mit einem Leerzeichen beginnen, wenn kein Zugriff vorhanden ist - ich nehme an, dies ist nicht das gewünschte Verhalten. Außerdem verifizieren Sie nicht, dass beide Pin-Nummern gleich sind. –

+0

Und \ s * macht den Raum optional, während mindestens ein Leerzeichen benötigt wird, daher sollte es \ s + sein. –

+0

Beide sind wahr! = D – Fernando

0

Es klingt wie Sie den ersten Raum wollen, auch wenn keine Zugriffsebene festgelegt ist? Wenn ja, ich denke, das den Trick tun sollten:

/^([1-5])? [a-z]{3,5}\d{3,5} +(\d{4}) +\2$/

Wenn der Raum ist optional, nur um es von Klammern innerhalb des ersten Satzes bewegen.

Um die Warnungen anzuzeigen, sollte ein einfaches if/else es tun.

+0

Ich glaube nicht, dass der erste 1 bis 5 Ziffern lang ist. Die Anweisungen sagen "eine Ziffer von 1 bis 5" – seth

+0

Ja, ich bezweifle es auch, aber sein Beispiel und Beschreibung sind widersprüchlich. – annakata

+0

Ups, du hast Recht! Fest, danke. –

2

Ein paar Problem, das ich sofort sehen:

\d{1,5} wird eine beliebige Ziffer entsprechen (0-9) für 1 bis 5 Vorkommen. zB 0001, 12,3,41332. Ich denke, Sie suchen nach [1-5], die eine Ziffer im Bereich von 1-5 entsprechen wird.

/s sollte \s

mit [a-z]{3,5}\b\d{3,5}\s sein Ich bin nicht sicher, warum Sie \b dort haben.

Fix diese Probleme zuerst denke ich.:)

+0

@ Jonathan: Danke für die Korrektur des Codes, wusste nicht, dass Sie Inline-Code-Blöcke tun können :) – MitMaro

4

Ok, nach Ihren Anweisungen dem Buchstaben (was ich bin nicht davon überzeugt ist, was Sie wirklich wollen) Sie verwenden können:

/^[1-5]?\s[a-z]{3,5}\d{3,5}\s+(\d{4})\s+(\1)$/ 

dieses Breaking down, das ist:

  • Anfang der Zeile
  • eine einzelne Ziffer zwischen 1 und 5, optional
  • ein Leerzeichen (streng genommen keine Leerzeichen)
  • zwischen 3 und 5 Kleinbuchstaben
  • zwischen 3 und 5 Ziffern
  • mindestens einen Raum
  • genau 4 Ziffern
  • mindestens einen Raum
  • das gleiche Muster von 4 Ziffern (die \ 1 ist hier entscheidend für das falsche Muster für die Zugriffsebene, ein zufälliges Wort brechen und es versäumen, eingeführt zu erfassen
  • Zeilenende

    Sie haben

  • ) mehrere Leerzeichen korrekt, wo dein Muster zusammenbricht.

+0

'\ s' entspricht allen Leerzeichen (z. B. Registerkarte), nicht nur Leerzeichen. Ansonsten, genau richtig. –

+0

Was macht '/ ^'? Ich weiß,^ist Startlinie, aber was ist das /? ist das wie Regex in Javascript zu tun? – Victor

+0

Sie haben ein paar Tippfehler, vielleicht ist eine Bearbeitung in Ordnung. – Nixuz

0

Versuchen Sie dieses:

^(?:[1-5])?[a-z]{3,5}\d{3,5} +(\d{4}) +\1$ 

Sie könnten zum Testen von regulären Ausdrücken my regex tool nützlich finden. Es hat einen "Erklären" -Modus, der einen Ausdruck unterbricht und beschreibt, was er macht, wenn Sie stecken bleiben.

Viel Glück!

+0

Ich denke, die Zugriffsebene zusammen mit dem Leerzeichen sind optional - dieser Ausdruck Kräfte beginnt mit einem Leerzeichen, wenn keine Zugriffsebene vorhanden ist, daher ([0-5] _)? anstelle von ([0-5])? _ oder [0-5]? _. –

+0

Nach dem Nachlesen denke ich, dass Sie recht haben müssen. Ich habe bearbeitet, um zu beheben, aber Ihre Antwort sieht sowieso besser aus. Vielen Dank! –

4
^(?:[1-5])?[a-z]{3,5}[0-9]{3,5} +([0-9]{4}) +\1$ 

Erklärung

 
    ^   Anchor start of line. 
    (?:[1-5])? Optional access level 1 to 5 followed by a single space, 
       the group is non-capturing. 
    [a-z]{3,5} User name with 3 to 5 lower case letters followed by 
    [0-9]{3,5} 3 to 5 digits. 
    _+   At least one space. 
    ([0-9]{4}) A 4 digit pin number captured into group \1. Without the 
       non-capturing group from above the pin number would be 
       captured into group \2. 
    _+   At least one space. 
    \1   A backreference to the pin number captured in group \1. 
    $   Anchor end of line. 
+1

Sie haben \ 1 in Ihrer Regex nicht verwendet. – SolutionYogi

+0

Danke, behoben. –

+0

Sie haben das() nicht eingeschlossen, um [0-9] {4} in Ihrem Regex zu erfassen. – Nefrubyr

-1

Was Sie beschreiben, ist keine reguläre Sprache, daher ist es nicht durch einen regulären Ausdruck analysiert werden kann. Das Problem ist Ihre Anforderungen 6 und 8: reguläre Ausdrücke haben keinen Speicher, daher ist es unmöglich zu überprüfen, dass die PINs in 6 und 8 identisch sind.

+0

Natürlich ist es möglich, es nennt sich eine "Rückreferenz". –

+0

@Pavel: Jörg ist theoretisch korrekt. Was irgendwelche praktisch nützlichen Paketgeräte beinhalten, umfassen Ausdrücke, die im theoretischen Sinn nicht "regelmäßig" sind, z. Sie verwenden Erfassungsgruppen und Rückverweise auf dasselbe. Die meisten Leute benutzen "regulären Ausdruck" in einem eher lockeren Sinn, und die Mehrheit der Minderheit wird nicht darüber aufgeregt ;-) –

+0

Es gibt keine "Rückreferenz" in regulären Ausdrücken. Vielleicht denken Sie an Regexps, die manchmal Rückreferenzen haben (und manchmal nicht). Aber das OP fragte speziell nach einem "regulären Ausdruck" und nicht nach einem Regexp. Diese beiden sind völlig verschiedene Dinge. Insbesondere sind Regexps typischerweise viel leistungsfähiger als reguläre Ausdrücke. –

0

Hier ist eine Python-Antwort, die die re.VERBOSE-Funktion zeigt, die sehr praktisch ist, wenn Sie morgen wiederkommen und verstehen wollen, was Ihre Regex macht.

Weitere Informationen finden Sie unter this. Sie werden keine Ranke oder ein Seil brauchen, um darauf zu schwingen. :-)

import re 
match_logon = re.compile(r""" 
    [1-5]?  # 1. start with an optional access level (a digit from 1 to 5) 
    [ ]   # 2. followed by a space 
    [a-z]{3,5} # 3. then a user name consisting of between 3 and 5 small letters 
    \d{3,5}  # 4. followed by between 3 and 5 digits 
    [ ]+  # 5. then one or more spaces 
    (\d{4,4}) # 6. and then a four digit pin number (captured for comparison) 
    [ ]+  # 7. then one or more spaces 
    \1   # 8. and the same pin again for confirmation.. 
    $   # match end of string 
    """, re.VERBOSE).match 
tests = [ 
    ("1 xyz123 9876 9876", True), 
    (" xyz123 9876 9876", True), # leading space? revisit requirement! 
    ("0 xyz123 9876 9876", False), 
    ("5 xyz123 9876 9876", False), # deliberate mistake to test the testing mechanism :-) 
    ("1 xy1234 9876 9876", False), 
    ("5 xyz123 9876 9875", False), 
    ("1 xyz123 9876 9876\0", False), 
    ] 
for data, expected in tests: 
    actual = bool(match_logon(data)) 
    print actual == expected, actual, expected, repr(data) 

Results: 
True True True '1 xyz123 9876 9876' 
True True True ' xyz123 9876 9876' 
True False False '0 xyz123 9876 9876' 
False True False '5 xyz123 9876 9876' 
True False False '1 xy1234 9876 9876' 
True False False '5 xyz123 9876 9875' 
True False False '1 xyz123 9876 9876\x00'