regex - online - regular expression replace
Regex para analizar el directorio y el nombre de archivo (8)
¿Que lenguaje? y por qué usar expresiones regulares para esta simple tarea?
Si debes :
^(.*)/([^/]*)$
te da las dos partes que querías Es posible que deba citar los paréntesis:
^/(.*/)//([^/]*/)$
dependiendo de su sintaxis de idioma preferido.
Pero sugiero que solo use la función de búsqueda de cadenas de su idioma que encuentre el último carácter "/", y divida la cadena en ese índice.
Estoy tratando de escribir una expresión regular que analizará el directorio y el nombre de archivo de una ruta totalmente calificada utilizando grupos coincidentes.
asi que...
/var/log/xyz/10032008.log
reconocería que el group 1 to be "/var/log/xyz"
y el group 2 to be "10032008.log"
Parece simple pero no puedo hacer que los grupos coincidentes trabajen por mi vida.
NOTA: Como señalaron algunos de los encuestados, probablemente este no sea un buen uso de las expresiones regulares. En general, prefiero usar el archivo API del idioma que estaba usando. Lo que en realidad estoy tratando de hacer es un poco más complicado que esto, pero hubiera sido mucho más difícil de explicar, así que elegí un dominio con el que todos estarían familiarizados para describir de manera más sucinta el problema de la raíz.
La mayoría de los lenguajes tienen funciones de análisis de ruta que ya le darán esto. Si tiene la capacidad, le recomendaría usar lo que le venga gratis de fábrica.
Asumiendo / es el delimitador de ruta ...
^(.*/)([^/]*)$
El primer grupo será cualquiera que sea la información del directorio / ruta, el segundo será el nombre del archivo. Por ejemplo:
- /foo/bar/baz.log : "/ foo / bar /" es la ruta, "baz.log" es el archivo
- foo / bar.log : "foo /" es la ruta, "bar.log" es el archivo
- / foo / bar : "/ foo /" es la ruta, "barra" es el archivo
- / foo / bar / : "/ foo / bar /" es la ruta y no hay archivo.
Prueba esto:
^(.+)/([^/]+)$
Prueba esto:
/^(//([^/]+//)*)(.*)$/
Sin embargo, dejará la barra final en el camino.
Evitaría hacer eso con Regex. Usaría los recursos incluidos en tu idioma para analizar los nombres de ruta y usar expresiones regulares solo para la búsqueda para la que se requiere su naturaleza.
¿Qué hay de esto?
[/]{0,1}([^/]+[/])*([^/]*)
Determinístico:
((/)|())([^/]+/)*([^/]*)
Estricto:
^[/]{0,1}([^/]+[/])*([^/]*)$
^((/)|())([^/]+/)*([^/]*)$
Una respuesta muy tardía, pero espero que esto ayude
^(.+?)/([/w]+/.log)$
Esto usa verificación lenta para /
, y acabo de modificar la respuesta aceptada
En idiomas que admiten expresiones regulares con grupos que no capturan :
((?:[^/]*/)*)(.*)
Explicaré la expresión regular gnarly explotando ...
(
(?:
[^/]*
/
)
*
)
(.*)
Lo que significan las partes:
( -- capture group 1 starts
(?: -- non-capturing group starts
[^/]* -- greedily match as many non-directory separators as possible
/ -- match a single directory-separator character
) -- non-capturing group ends
* -- repeat the non-capturing group zero-or-more times
) -- capture group 1 ends
(.*) -- capture all remaining characters in group 2
Ejemplo
Para probar la expresión regular, utilicé el siguiente script Perl ...
#!/usr/bin/perl -w
use strict;
use warnings;
sub test {
my $str = shift;
my $testname = shift;
$str =~ m#((?:[^/]*/)*)(.*)#;
print "$str -- $testname/n";
print " 1: $1/n";
print " 2: $2/n/n";
}
test(''/var/log/xyz/10032008.log'', ''absolute path'');
test(''var/log/xyz/10032008.log'', ''relative path'');
test(''10032008.log'', ''filename-only'');
test(''/10032008.log'', ''file directly under root'');
El resultado del script ...
/var/log/xyz/10032008.log -- absolute path
1: /var/log/xyz/
2: 10032008.log
var/log/xyz/10032008.log -- relative path
1: var/log/xyz/
2: 10032008.log
10032008.log -- filename-only
1:
2: 10032008.log
/10032008.log -- file directly under root
1: /
2: 10032008.log