7

Ruby's Dir.glob accepts a glob String that has some regular expression behaviour, but it doesn't have the full abilities of Regexp.

What alternatives in Ruby (including core and gems) are there to Dir.glob that allow the use of Regexp to match file paths?

Eliot Sykes
  • 9,616
  • 6
  • 50
  • 64
  • 1
    You may be able to use `Find` to walk directories and do a regex against them [?] http://stackoverflow.com/a/1281222/32453 – rogerdpack Aug 20 '15 at 18:31
  • [The documentation](http://ruby-doc.org/core-2.2.3/Dir.html#method-c-glob) says it clearly: "Note that this pattern is not a regexp, it's closer to a shell glob." Consider it like you would a pattern to a `ls` at the command-line. – the Tin Man Aug 20 '15 at 20:17
  • [Find](http://ruby-doc.org/stdlib-2.2.3/libdoc/find/rdoc/index.html) is an excellent, though underused, way to walk a directory hierarchy. Using regexp with Dir and Find is easy done using `select` and `reject` to find matches, or within blocks using `next` or `prune`. – the Tin Man Aug 20 '15 at 20:19

2 Answers2

12

The thing with glob is that it can match subpaths. When you write Dir.glob('*/*') it'll return all the files and directories directly under subdirectories of the current directories. It can do that because glob patterns are simple enough for the computer to understand - if it was regex it would have to scan the entire filesystem and compare each path with the pattern, which is simply too much.

However, you can combine - use Dir.glob to choose where to search, and grep to choose what to search:

[1] pry(main)> Dir.glob('/usr/lib/*').grep(/\/lib[A-Z]+\.so$/)
=> ["/usr/lib/libFLAC.so", "/usr/lib/libEGL.so", "/usr/lib/libHACD.so", "/usr/lib/libLTO.so", "/usr/lib/libGLEW.so", "/usr/lib/libGL.so", "/usr/lib/libSDL.so", "/usr/lib/libGLU.so", "/usr/lib/libSM.so", "/usr/lib/libICE.so"]
Idan Arye
  • 12,402
  • 5
  • 49
  • 68
3

Although full regex isn't supported, you can do tricks like the following in glob

Dir.glob("folder_with_images/*.{jpg,png}")
Jack Kinsella
  • 4,491
  • 3
  • 38
  • 56
  • I used this to do `Dir.glob("test/models/#{model}{/*_test.rb,_test.rb}` to find `test/model/abc_test.rb` as well as `test/model/abc/my_sub_test.rb` – Pelle May 21 '21 at 13:18