【问题标题】:Regex to allow only these [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" [closed]正则表达式只允许这些 [A-Z] / [a-z] / [0-9] / "-" / "." /“_”/“~”[关闭]
【发布时间】:2021-01-26 06:54:21
【问题描述】:

我需要找到一种使用正则表达式的方法来验证我作为参数得到的字符串

这必须是一个仅由以下字符组成的单词:[A-Z] / [a-z] / [0-9] / "-" / "." /“_”/“~”

我尝试过的

   var pattern = @"^[a-zA-Z0-9~\-_.]\S{42,128}$";
   if (!Regex.IsMatch(authorizationRequest.CodeChallenge, pattern))
   {
        return new PkceResponse
        {
             IsValid = false,
             Error = OIDCErrorCodes.InvalidRequest,
             ErrorDescription = "Code Challenge contains invalid characters",
             ParameterName = "code_challenge"
        };
   }

但我的测试因以下输入而失败: longenoughlongenoughlongenoughlongenoughlongenoughlongenoughlongenoughlongenoughAABSC__-......~~~.~-! 我错过了什么?

【问题讨论】:

  • @John 限制空格,据我了解
  • 我认为您错过了 \S,它匹配任何非空白字符,包括末尾的 !
  • 我在我的系统上运行了你的代码,它可以工作并且模式匹配。怎么了?

标签: c# .net regex


【解决方案1】:

你的表达如下:

^[a-zA-Z0-9~\-_.]\S{42,128}$

让我们把它分解成它的组件:

  • ^ - 匹配输入的开头。
  • [a-zA-Z0-9~\-_.] - 匹配单个字符 a-z A-Z 0-9 ~ - _ 或 .
  • \S - 匹配除空白字符以外的任何字符。
  • {42,128} - 匹配前一个元素至少 42 次,最多 128 次。在这种情况下,前一个元素是\S
  • $ - 匹配输入的结尾,或匹配输入结尾的最后一个 \n 之前的点。

Source for most definitions

所以我们可以看到您的正则表达式当前执行以下操作:

它首先匹配单个字符 a-z A-Z 0-9 ~ - _ 或 .在字符串的开头。然后它匹配任何非空白字符 42-128 次,并期望输入的结尾紧随其后。这意味着我们期望一个总长度为 43-129 个字符的字符串。

正如你的问题所述,你只想匹配那些特定的字符,所以你的表达实际上应该是这样的(我已经删除了\S):

^[a-zA-Z0-9~\-_.]{42,128}$

至于您的具体意见:

longenoughlongenoughlongenoughlongenoughlongenoughlongenoughlongenoughlongenoughAABSC__-......~~~.~-!

您的输入末尾似乎包含了一个感叹号 (!),这当然不符合您的约束条件。

【讨论】:

  • 我的第一个想法是(我又被骗了)使用简写 \w 代替 [A-Za-z0-9_],但在 .NET 中,这将匹配 ASCII 托盘之外的字符。为了强制执行正确的行为,我们可以在 options 参数中包含 ECMAScript 选项。这样就可以使用^[\w~.-]{42,128}$,但我想一般来说,在 .NET 表达式中更具描述性会更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 2016-06-01
  • 2012-08-05
  • 1970-01-01
  • 2011-09-17
相关资源
最近更新 更多