【问题标题】:Normalize a Windows path or URI using RegEx in .NET在 .NET 中使用 RegEx 规范化 Windows 路径或 URI
【发布时间】:2014-07-28 05:20:26
【问题描述】:

我正在尝试构建一个正则表达式,我可以使用它来匹配本地 Windows 路径或 URI 中的所有重复斜杠,然后用单个斜杠替换它们,同时离开URI 方案或本地驱动器部分未更改

这是我正在测试的示例:

http://www.tempuri.org//path//////to/file.ext
c:/path-to/file.ext
c://path-to/file.ext
http://www.tempuri.org
http://www.tempuri.org//
http://www.tempuri.org///
ftp://www.tempuri.org////
file:///c:/path-to//file.ext
file:////c:/path-to/file.ext
file://///c://path-to/file.ext

这就是我想从这些中得到的:

http://www.tempuri.org/path/to/file.ext
c:/path-to/file.ext
c:/path-to/file.ext
http://www.tempuri.org
http://www.tempuri.org/
http://www.tempuri.org/
ftp://www.tempuri.org/
file:///c:/path-to/file.ext
file:///c:/path-to/file.ext
file:///c:/path-to/file.ext

我得到的最接近的是:

(?<!(file:)|(ftp|gopher|http|https|ldap|mailto|net\.pipe|net\.tcp|news|nntp|telnet|uuid)[:])/+

但是用一个斜杠替换匹配项会将file:/// 变成file://。除了最后一种情况,似乎工作得很好。

【问题讨论】:

  • 您需要一次性完成吗?例如,您可以将字符串拆分为一个数组,其中一个是 URI 方案,而其余的路径是另一个?
  • 这不是必须,但如果可能的话,一次性完成会更优雅。现在我正在单独处理file:/// 案子,但我希望能摆脱它。
  • 顺便说一下,+1 用于在您的问题中提供示例代码和预期结果!
  • 这是XY Problem。您实际上想做什么,因为您为我们提供的解决方案无法解决您未描述的问题。

标签: .net regex windows path normalization


【解决方案1】:

我比较熟悉 PCRE 格式,但是看看这个:

(                     # Capture group

(?<!\/)\/             # Look for / that does not follow another /

# Look for C:/
(?(?<=\b[a-zA-Z]:\/)  # if...
                      # then look for any more / to remove
  |                   # else

# Look for file:///
(?(?<=\bfile:\/)      # if...
  \/\/                # then look for // right after it
  |                   # else

# Look for http:// or ftp://, etc.
(?(?<=:\/)            # if [stuff]:/
  \/                  # then look for /
  |                   # else

)
)
)
)
\/+                   # everything else with / after it

直播:http://regex101.com/r/hU4yI4

基本上,我正在使用conditional statement 寻找这些标准:

If / is preceded by:
   \b[a-zA-Z]:     then     /
   \bfile:         then     ///
   \b\w{2,}:       then     /   (basically anything else, like ftp:, https:, etc.)

没有所有的空白,整个组看起来更像:

((?<!\/)\/(?(?<=\b[a-zA-Z]:\/)|(?(?<=\bfile:\/)\/\/|(?(?<=:\/)\/|))))\/+

但是,我不确定这将如何插入 C# 的正则表达式。它可能会直接插入,或者可能需要一些按摩(这就是为什么我将 cmets 留在代码中以便于阅读和更多边缘情况)。

【讨论】:

  • 哇,这是一个了不起的答案,特别是因为一步一步的 cmets,谢谢!但是,在处理file:/// 中的多余斜杠时,它在 C# 的正则表达式中的工作方式似乎不同。您可以在 regexhero.net/tester/?id=0494980d-bd07-4d3c-a8c0-258eba6d0c60 上看到它。
  • 另外 +1 用于将表达式分解为更易于理解的组件并指出 if-then-else 推理。我正在以错误的方式考虑向后看。我正在尝试如何让它在 C# 中工作,我会回来报告。
  • 好的,开始工作了。原来我使用的是regex.Replace(inputString, "/"),而不是使用反向引用的regex.Replace(inputString, "$1")。非常感谢您的帮助!
猜你喜欢
  • 2010-11-18
  • 2015-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-27
  • 2010-11-17
  • 2010-12-17
  • 2010-10-15
相关资源
最近更新 更多