【问题标题】:Turning a string match requirement into a Regular Expression将字符串匹配要求转换为正则表达式
【发布时间】:2009-07-08 18:55:26
【问题描述】:

我在编写正则表达式时遇到问题。我怎么能写出以下内容:

  1. 从可选的访问级别开始(1 到 5 的数字)
  2. 后跟一个空格
  3. 然后是由 3 到 5 个小写字母组成的用户名
  4. 后跟 3 到 5 位数字
  5. 然后是一个或多个空格
  6. 然后是四位数的密码
  7. 然后是一个或多个空格
  8. 再次使用相同的密码进行确认..

如果信息有效,请显示“谢谢”提示。否则“输入的信息有误。”

我写了以下,但它不能正常工作:

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

我将不胜感激。

【问题讨论】:

  • 如果你举几个例子会很有帮助。那会更容易理解然后阅读您的描述
  • 确认!正则表达式!逃跑!逃跑! xkcd.com/208
  • @PiPeep:当它出现时我很喜欢它:P @seth:这就是我的想法,这就是为什么我没有在我的答案中发布正则表达式:)
  • 谈编辑互相踩脚!
  • 示例与描述...我认为描述(规范)比许多示例要好得多。它准确地说明了需要什么,并且(几乎)没有猜测的余地。如果有很多例子,每个人都会问“总是有 3 位数字吗?”,“可以有多少个空格?”,对于选择不当的例子,“你所有的例子都有一个 3 作为密码的第二个数字 - 是这是一个要求?”。所以我不得不说,这可能是迄今为止我在 SO 上看到的对正则表达式预期行为的最佳描述。

标签: javascript regex


【解决方案1】:

好的,按照你的指示信中(我不相信这是你真正想要的)你可以使用:

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

分解如下:

  • 行首

  • 1 到 5 之间的单个数字,可选

  • 一个空格(严格来说是任何空格)

  • 3 到 5 个小写字母

  • 3 到 5 位数之间

  • 至少一个空格

  • 正好 4 位数

  • 至少一个空格

  • 4 位数字的相同模式(\1 在这里很关键)

  • 行尾

    您为访问级别引入了错误的模式、随机断词并且未能正确捕获多个空格,这是您的模式出现故障的地方。

【讨论】:

  • \s 匹配任何空格(例如制表符),而不仅仅是空格。否则,就当场了。
  • '/^' 有什么作用?我知道 ^ 是行首,但 / 是什么?这就是在javascript中做正则表达式的方法吗?
  • @Vinay,是的,我在上面说了很多,但我怀疑这是更可取的@Victor - / 只是开始正则表达式,cf 最后相同表达式的
  • @Nixuz - 修正了一些琐碎的拼写错误,但确实没有什么值得一提的 - 你有什么想法吗?
  • “2. 后跟一个空格”表示只有在存在访问级别时才应该存在第一个空格 - 以空格开始输入似乎是错误的,不是吗?
【解决方案2】:
^(?:[1-5] )?[a-z]{3,5}[0-9]{3,5} +([0-9]{4}) +\1$

说明

^ 锚定线的起点。 (?:[1-5])?可选访问级别 1 到 5,后跟一个空格, 该组未捕获。 [a-z]{3,5} 用户名,后跟 3 到 5 个小写字母 [0-9]{3,5} 3 到 5 位数字。 _+ 至少一个空格。 ([0-9]{4}) 捕获到组 \1 中的 4 位密码。没有 来自引脚号上方的非捕获组将是 捕获到组\2。 _+ 至少一个空格。 \1 对组 \1 中捕获的引脚号的反向引用。 $ 锚定行尾。

【讨论】:

  • 你没有在你的正则表达式中使用 \1。
  • 您也没有在正则表达式中包含 ( ) 来捕获 [0-9]{4}。
  • 为什么一切都在解释中而不是在正则表达式中?!?这是怎么回事?!? :D
【解决方案3】:

我马上看到的几个问题:

\d{1,5} 将匹配任何数字 (0-9) 1 到 5 次。即 0001, 12,3,41332。我认为您正在寻找将匹配 1-5 范围内的一位数字的 [1-5]。

/s 应该是\s

[a-z]{3,5}\b\d{3,5}\s 我不知道你为什么有\b

我想先解决这些问题。 :)

【讨论】:

  • @Jonathan:谢谢你修复代码,不知道你可以做内联代码块:)
【解决方案4】:

试试这个:([1-5])?\s[a-z]{3,5}(\s*\d{4}){2}

【讨论】:

  • 如果没有访问级别,输入必须以空格开头 - 我认为这不是所需的行为。此外,您无需验证两个引脚号是否相等。
  • 而 \s* 使空格是可选的,而至少需要一个空格,因此它应该是 \s+。
【解决方案5】:

听起来你想要第一个空格,即使没有指定访问级别?如果是这样,我认为这应该可以解决问题:

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

如果空格是可选的,只需将其移到第一组括号内即可。

要显示警报,应该使用简单的 if/else。

【讨论】:

  • 我不认为第一个是 1 到 5 位数长。说明说“从 1 到 5 的数字”
  • 是的我也怀疑,但他的例子和描述是矛盾的。
  • 我认为访问级别和空格是可选的 - 如果没有访问级别,此表达式强制以空格开头,因此 ([0-5]_)?而不是 ([0-5])?_ 或 [0-5]?_.
【解决方案6】:

试试这个:

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

您可能会发现my regex tool 对测试正则表达式很有用。它有一个“解释”模式,如果你被卡住了,它会分解一个表达式并描述它的作用。

祝你好运!

【讨论】:

  • 我认为访问级别和空格是可选的 - 如果没有访问级别,此表达式强制以空格开头,因此 ([0-5]_)?而不是 ([0-5])?_ 或 [0-5]?_.
  • 重读后,我想你一定是对的。我已经编辑修复,但无论如何你的答案看起来更好。谢谢!
【解决方案7】:

这是一个 Python 答案,展示了 re.VERBOSE 工具,如果您想明天回来了解您的正则表达式在做什么,这非常方便。

请参阅this 了解更多说明。您不需要藤蔓或绳索即可摆动。 :-)

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'

【讨论】:

    【解决方案8】:

    您所描述的不是正则语言,因此它不能被正则表达式解析。问题是你的要求 6 和 8:正则表达式没有记忆,因此无法检查 6 和 8 中的 PIN 是否相同。

    【讨论】:

    • @Pavel:Joerg 在理论上是正确的。任何实际有用的包实现的内容包括在理论意义上不是“常规”的表达式,例如他们使用捕获组和对相同的反向引用。大多数人在相当宽松的意义上使用“正则表达式”,大多数少数人对此并不感到不安;-)
    • 正则表达式中没有“反向引用”这样的东西。您可能会想到正则表达式,它有时确实 有反向引用(有时没有)。但是 OP 专门询问“正则表达式”,而 not 询问正则表达式。这两个是完全不同的东西。特别是,正则表达式通常比正则表达式强大得多。
    • @Joerg:OP 说的是“正则表达式”,但就像 99.99% 的 OP 和回答者一样,他真正的意思是“正则表达式以某种特定的编程语言或包实现”,并且不知道(并且不知道'不需要知道)你的词典中的“常规语言”是什么。习惯就好。
    猜你喜欢
    • 2019-06-23
    • 1970-01-01
    • 2015-11-30
    • 2012-06-05
    • 2013-12-25
    • 1970-01-01
    相关资源
    最近更新 更多