Necesito escribir un archivo glob que coincida con todos los archivos, excepto los que se encuentran dentro de una determinada carpeta (por ejemplo, todos los archivos, excepto los que se encuentran dentro de la carpeta de alto nivel foo/ .
He llegado al siguiente globo:
!(foo)/**/* Sin embargo, este glob no parece coincidir con ningún archivo en Ruby's File.fnmatch (incluso con FNM_PATHNAME y FNM_DOTMATCH configurados en true .
Además, el intérprete global de Ruby parecía tener un comportamiento diferente al de JavaScript:
El intérprete global de JavaScript coincide con todas las cadenas
El intérprete de Ruby glob no coincide con ninguna cadena:
2.6.2 :027 > File.fnmatch("!(foo)/**/*", "hello/world.js") => false 2.6.2 :028 > File.fnmatch("!(foo)/**/*", "test/some/globs") => false 2.6.2 :029 > File.fnmatch("!(foo)/**/*", "foo/bar/something.txt") => falseSi realmente necesita usar un glob, puede enumerar lo que está permitido, haciéndolo equivalente a la negación:
extglob = "{[^f]*,f,f[^o]*,fo,fo[^o]*,foo?*}/**/*" File.fnmatch(extglob, "hello/world.js", File::FNM_EXTGLOB | File::FNM_PATHNAME) #=> true File.fnmatch(extglob, "test/some/globs", File::FNM_EXTGLOB | File::FNM_PATHNAME) #=> true File.fnmatch(extglob, "foo/bar/something.txt", File::FNM_EXTGLOB | File::FNM_PATHNAME) #=> false File.fnmatch(extglob, "food/bar/something.txt", File::FNM_EXTGLOB | File::FNM_PATHNAME) #=> true {[^f]*,f,f[^o]*,fo,fo[^o]*,foo?*} significa:
fff y cuyo segundo carácter no sea una ofofo y cuyo tercer carácter no sea una ofoo si tiene al menos un carácter másSi su literal de cadena es demasiado largo, podría convertirse en un dolor generar un globo que lo niegue, entonces, ¿por qué no hacer una función para él?
def extglob_neg str str.each_char.with_index.with_object([]) do |(_,i),arr| arr << "#{str[0,i]}[^#{str[i]}]*" arr << str[0..i] end.join(',').prepend('{').concat('?*}') end extglob_neg "Food" #=> "{[^F]*,F,F[^o]*,Fo,Fo[^o]*,Foo,Foo[^d]*,Food?*}"nota: no implementé ningún escape global en esta función porque parecía un poco complicado. Yo podría, sin embargo, estar equivocado