【问题标题】:Regex to validate port number正则表达式验证端口号
【发布时间】:2012-10-09 16:54:42
【问题描述】:

我正在使用这个正则表达式(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3} 来验证端口号。不知何故,这不起作用。这有什么问题?谁能指出我。

【问题讨论】:

  • 你想做什么?也许发布一些失败的单元测试代码或什么?
  • 你想要什么端口号 2 验证..它们是在特定范围内还是你想要它 2 只是验证
  • @Fake.It.Til.U.Make.It 我只想验证从 1 到 65535。
  • @SohamDasgupta 不需要在这里使用正则表达式..只需将数字解析为 int 然后检查它是否在所需范围内!

标签: regex vb.net .net-2.0


【解决方案1】:

不工作到底是什么意思?

您可以尝试以下方式:^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$(从here 获得)。

这将确保任何给定的字符串都是数字并且在065535 的范围之间。

假设您的正则表达式匹配相同的范围,它缺少开始和结束锚点(分别为^$),因此它允许除了实际端口之外的其他字符串。

【讨论】:

  • 我正在使用 DexExpress 文本框并将此正则表达式用作掩码。但是在运行时它会产生一个错误,说明语法不正确。
  • @SohamDasgupta:也许您需要将所有内容都放在引号之间?也许查看the 文档会有所帮助。
  • 放置 qoutes 是我 10 年前开始编程时学到的东西。无论如何,谢谢。
  • 第一部分 ([0-9]{1,4}) 错误地允许 0000。应该是[1-9]\\d{0,3}|0
  • 嗨,@elfan 接受 00 或 000 或 0000 我偶然发现了这个条目并意识到模式中有一个小错误:“更正您的正则表达式后:Port = '([1-9 ][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0- 9]{2}|655[0-3][0-9]|6553[0-5])'; // 1..65535" 此模式允许用于 1-65539 ​​之间的范围,它应该是:端口 = '([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65 [0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])'; // 1..65535 github.com/findhit/proxywrap/issues/13
【解决方案2】:

当我们在 Google 上搜索“如何验证端口号”时,我们不幸落到了这里

但是(除非你真的别无选择......),

Regex 显然不是验证端口号的方法!

“一个”(稍微好一点)的方式可能是:

step 1: Convert your string into number, and return FALSE if it fails
step 2: return TRUE if your number is in [1-65535] range, and FALSE otherwise

各种原因,为什么 Regex 不是正确的方式?

  • 代码可读性(需要几分钟才能理解)
  • 代码稳健性(有多种方法可以引入拼写错误,需要进行单一测试)
  • 代码灵活性(如果端口号可以扩展为 64 位数字会怎样!?)
  • 等。 ...

【讨论】:

  • 好建议。对于第 1 步,我们可以使用System.UInt16.Tryparse(string value, out int result)。尽管UInt16 范围也包括零,这不是有效的端口号。
【解决方案3】:

Number() 是你想要的函数 "123a" 返回 NAN

parseInt() 截断尾随字母“123a”返回 123

<input type="text" id="txtFld" onblur="if(Number(this.value)>0 && Number(this.value)<65536){alert('valid port number');}" />

【讨论】:

  • 太晚了:),但这显然是错误的。例如,您可以使用“2e2”对其进行测试。
【解决方案4】:

这是我用来验证防火墙端口设置的示例。原始答案将匹配 2 个字符串。我只能匹配 1 个字符串。

(6553[0-5]|655[0-2][0-9]|65[0-4][0-9][0-9]|6[0-4][0-9][0-9][0-9][0-9]|[1-5](\d){4}|[1-9](\d){0,3})

要获得:22,24:100,333,678,100:65535 我的完整验证(只会返回 1 个匹配项)是

(6553[0-5]|655[0-2][0-9]|65[0-4][0-9][0-9]|6[0-4][0-9][0-9][0-9][0-9]|[1-5](\d){4}|[0-9](\d){0,3})(:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9][0-9]|6[0-4][0-9][0-9][0-9][0-9]|[1-5](\d){4}|[0-9](\d){0,3}))?(,(6553[0-5]|655[0-2][0-9]|65[0-4][0-9][0-9]|6[0-4][0-9][0-9][0-9][0-9]|[1-5](\d){4}|[0-9](\d){0,3}){1}(:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9][0-9]|6[0-4][0-9][0-9][0-9][0-9]|[1-5](\d){4}|[0-9](\d){0,3}))?)*

【讨论】:

    【解决方案5】:

    更严格的方法是使用正则表达式匹配最多 5 位的所有数字 使用以下字符串:

    *(^[1-9]{1}$|^[0-9]{2,4}$|^[0-9]{3,4}$|^[1-5]{1}[0-9]{1}[0-9]{1}[0-9]{1}[0-9]{1}$|^[1-6]{1}[0-4]{1}[0-9]{1}[0-9]{1}[0-9]{1}$|^[1-6]{1}[0-5]{1}[0-4]{1}[0-9]{1}[0-9]{1}$|^[1-6]{1}[0-5]{1}[0-5]{1}[0-3]{1}[0-5]{1}$)*
    

    【讨论】:

      【解决方案6】:

      npinti 接受的答案是不正确的。例如,它不允许输入端口号 1000。对我来说,这个(不好,我是初学者)可以正常工作:

      /^((((([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-6][0-5][0-5][0-3][0-5])))))$/

      【讨论】:

        【解决方案7】:
        "^((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4}))$"
        

        它将允许 0-65535 之间的所有内容。

        【讨论】:

          【解决方案8】:

          这是排除以 0 开头的端口的单端口正则表达式验证

          ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])


          这是对端口范围的验证(例如 1111-1111)

          ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(-([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?$


          链接:

          https://github.com/findhit/proxywrap/issues/13

          【讨论】:

            【解决方案9】:

            也登陆这里,专门搜索 REGEX 来验证端口号。 我看到批准的解决方案尚未修复以涵盖所有方案(例如:007 端口等),其他站点的解决方案也未更新 (eg)。

            达到与saber tabatabaee yazdi 相同的最小解决方案,应该正确覆盖1-65535 范围:

            ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$

            享受吧!

            【讨论】:

              【解决方案10】:

              @npinti 的答案允许在端口号中使用前导零,并且端口 0 表示选择任何可用端口,所以我会排除它,因此正则表达式变为

              ^([1-9][0-9]{0,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$
              

              如果你想允许端口 0 那么

              ^(0|[1-9][0-9]{0,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$
              

              【讨论】:

              • 我真的很喜欢这个答案的意图,因为我现在有完全相同的问题。请注意,您的主要区别在于第一个捕获组允许[1-9][0-9]{0,4},但这意味着像 99999 这样的数字可以进入,这违反了问题。我会继续尝试看看是否可以找到更正。
              • 我想你的意思是改用[1-9][0-9]{0,3}?这将涵盖 1-9999(含),但不允许使用前导零。
              【解决方案11】:

              解决办法:

              Dim Minlenght As Integer = 1
              Dim Maxlenght As Integer = 65536
              
              Regex.IsMatch(sInput,"(^\d{0},{1}$)", "{" + Minlenght, Maxlenght + "}")
              

              【讨论】:

                【解决方案12】:
                ^((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0][0-9]{1,4})|([0-9]{1,4}))$
                

                我已经用 Junit 测试了上面的正则表达式,从 0-65535 运行 for 循环

                例如:00001 - 65535 前导零 1 - 65535 不带前导零 例如:====

                1. (6553[0-5]) : 65530-65535
                2. (655[0-2][0-9]) : 65500-65529
                3. (65[0-4][0-9]{2}): 65000-65499
                4. (6[0-4][0-9]{3}) : 60000-64999
                5. ([1-5][0-9]{4}) : 10000-59999
                6. ([0-5]{0,5}) : 00000-55555(用于前导零)
                7. ([0][0-9]{1,4}) : 00000-09999(用于前导零)
                8. ([0-9]{1,4}) : 0000-9999(用于前导零)

                【讨论】:

                  【解决方案13】:

                  如果变量是介于 1 和 65536(含)之间的整数,则...

                  if [[ "$port" =~ ^[0-9]+$ && $port -ge 1 && $port -le 65536 ]]; then
                  

                  【讨论】: