首页 > 解决方案 > 通过 rfc8141 匹配 URN 的正则表达式

问题描述

我正在努力寻找可以匹配rfc8141中描述的 URN 的正则表达式。我试过这个:

\A(?i:urn:(?!urn:)(?<nid>[a-z0-9][a-z0-9-]{1,31}):(?<nss>(?:[a-z0-9()+,-.:=@;$_!*']|%[0-9a-f]{2})+))\z

但是这个只匹配没有组件的URN的第一部分。

例如,假设我们有相应的 URN:urn:example:a123,0%7C00~&z456/789?+abc?=xyz#12/3我们应该匹配以下组:

标签: c#.netregexurn

解决方案


我还没有阅读所有规范,因此可能还有其他规则要实施,但它应该让您了解可选组件:

\A(?i:urn:(?!urn:)(?<nid>[a-z0-9][a-z0-9-]{1,31}):(?<nss>(?:[-a-z0-9()+,.:=@;$_!*'&~\/]|%[0-9a-f]{2})+)(?:\?\+(?<rcomponent>.*?))?(?:\?=(?<qcomponent>.*?))?(?:#(?<fcomponent>.*?))?)\z

解释:

  • (?<nss>(?:[-a-z0-9()+,.:=@;$_!*'&~\/]|%[0-9a-f]{2})+):-已移至允许的字符中考虑的列表的开头,否则表示“范围从,.”。字符&, ~and /(必须用“\”转义)也已添加到列表中,否则它将与您的示例不匹配。
  • 可选组件::(?:\?\+(?<rcomponent>.*?))?在可选的非捕获组内(?:)?,以防止捕获标识符(?+?=部分#)。字符?+必须用“\”转义。将捕获任何内容 ( .) 但在惰性模式 ( *?) 中,否则找到的第一个组件将捕获所有内容,直到字符串结尾。

请参阅Regex101中的工作示例

希望有帮助


推荐阅读