简体   繁体   English

Ruby正则表达式/(\\/.*?(?=\\/|$)){2}/

[英]Ruby regexp /(\/.*?(?=\/|$)){2}/

My regexp behaves just like I want it to on http://regexr.com , but not like I want it in irb. 我的正则表达式的行为就像我希望它在http://regexr.com ,但不像我想在IRB。

I'm trying to make a regular expression that will match the following: 我正在尝试制作一个符合以下条件的正则表达式:

A forward slash, 
then 2 * any number of random characters (i.e. `.*`), 
  up to but not including another / 
  OR the end of the string (whichever comes first)

I'm sorry as that was probably unclear, but it's my best attempt at an English translation. 我很抱歉,因为可能还不清楚,但这是我最好的英语翻译尝试。

Here's my current attempt and hopefully that will give you a better idea of what I'm trying to do: 这是我当前的尝试,希望可以使您对我正在尝试做的事情有更好的了解:

/(\/.*?(?=\/|$)){2}/

The usage scenario is I want to be able to take a path like /foo/bar/baz/bin/bash and shorten it to the level I'm at in the filesystem, in this case the second level ( /foo/bar ). 使用场景是我希望能够采用/foo/bar/baz/bin/bash类的路径并将其缩短到我在文件系统中所处的级别,在这种情况下为第二级( /foo/bar ) 。 I'm trying to do this using the command path.scan(-regex-).shift . 我正在尝试使用命令path.scan(-regex-).shift来执行此操作。

The usage scenario is I want to be able to take a path like /foo/bar/baz/bin/bash and shorten it to the level I'm at in the filesystem, in this case the second level (/foo/bar) 使用场景是我希望能够采用/ foo / bar / baz / bin / bash之类的路径并将其缩短到我在文件系统中所处的级别,在这种情况下为第二级(/ foo / bar)

Ruby already has a class for handling paths, Pathname . Ruby已经有一个用于处理路径的类Pathname You can use Pathname#relative_path_from to do what you want. 您可以使用Pathname#relative_path_from来执行所需的操作。

require 'pathname'

path = Pathname.new("/foo/bar/baz/bin/bash")

# Normally you'd use Pathname.getwd
cwd  = Pathname.new("/foo/bar")

# baz/bin/bash
puts path.relative_path_from(cwd)

Regexes just invite problems, like assuming the path separator is / , not honoring escapes, and not dealing with extra / . 正则表达式只会引发问题,例如假设路径分隔符为/ ,不接受转义符,并且不处理多余的/ For example, "//foo/bar//b\\\\/az/bin/bash" . 例如, "//foo/bar//b\\\\/az/bin/bash" // is particularly common in code which joins together directories using paths.join("/") or "#{dir}/#{file} . //在使用paths.join("/")"#{dir}/#{file} paths.join("/")将目录连接在一起的代码中特别常见。

For completeness, the general way you match a single piece of a path is this. 为了完整起见,匹配单个路径的一般方法是这样。

%r{^(/[^/]+)}

That's the beginning of the string, a / , then 1 or more characters which are not / . 那是字符串的开始,一个/ ,然后是1个或多个不是/字符。 Using [^/]+ means you don't have to try and match an optional / or end of string, a very useful technique. 使用[^/]+意味着您不必尝试匹配可选的/或字符串结尾,这是一种非常有用的技术。 Using %r{} means less leaning toothpicks . 使用%r{}意味着更少的牙签

But this is only applicable to a canonicalized path. 但这仅适用于规范化路径。 It will fail on //foo//b\\\\/ar/ . 它将在//foo//b\\\\/ar/上失败。 You can try to fix up the regex to deal with that, or do your own canonicalization, but just use Pathname. 您可以尝试修复正则表达式以解决该问题,也可以自己进行规范化,但只需使用路径名即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM