regular - Regex: para sacar una subcadena entre dos etiquetas en una cadena
probar expresiones regulares (9)
Tengo un archivo en el siguiente formato:
Data Data Data [Start] Data I want [End] Data
Me gustaría obtener los Data I want
de entre las etiquetas [Start]
y [End]
usando un Regex. ¿Alguien puede mostrarme cómo se puede hacer esto?
Bueno, si usted garantiza que cada etiqueta de inicio va seguida de una etiqueta final, entonces lo siguiente funcionaría.
/[start/](.*?)/[end/]
Sin embargo, si tiene texto complejo como el siguiente:
[start] sometext [start] sometext2 [end] sometext [end]
entonces se encontraría con problemas con Regex.
Ahora el siguiente ejemplo extraerá todos los enlaces activos en una página:
''/<a(.*?)a>/i''
En el caso anterior, podemos garantizar que no habrá ningún caso anidado de:
''<a></a>''
Entonces, esta es una pregunta compleja y no se puede resolver simplemente con una respuesta simple.
Con Perl puede rodear los datos que desee con () y extraerlos más tarde, quizás otros idiomas tengan una función similar.
if ($s_output =~ /(data data data data START(data data data)END (data data)/)
{
$dataAllOfIt = $1; # 1 full string
$dataInMiddle = $2; # 2 Middle Data
$dataAtEnd = $3; # 3 End Data
}
Consulte esta pregunta para extraer texto entre etiquetas con espacios y puntos ( .
)
[/S/s]
es el que utilicé
Regex para que coincida con cualquier personaje, incluidas las nuevas líneas
Leer el texto con los corchetes [], es decir [Inicio] y [Fin] y validar la matriz con una lista de valores. jsfiddle http://jsfiddle.net/muralinarisetty/r4s4wxj4/1/
var mergeFields = ["[sitename]",
"[daystoholdquote]",
"[expires]",
"[firstname]",
"[lastname]",
"[sitephonenumber]",
"[hoh_firstname]",
"[hoh_lastname]"];
var str = "fee [sitename] [firstname] /
sdfasd [lastname] ";
var res = validateMeargeFileds(str);
console.log(res);
function validateMeargeFileds(input) {
var re = //[/w+]/ig;
var isValid;
var myArray = input.match(re);
try{
if (myArray.length > 0) {
myArray.forEach(function (field) {
isValid = isMergeField(field);
if (!isValid){
throw e;
}
});
}
}
catch(e) {
}
return isValid;
}
function isMergeField(mergefield) {
return mergeFields.indexOf(mergefield.toLowerCase()) > -1;
}
Se puede encontrar una discusión más completa sobre los peligros de usar una expresión regular para encontrar etiquetas coincidentes en: http://faq.perl.org/perlfaq4.html#How_do_I_find_matchi . En particular, tenga en cuenta que las etiquetas de anidamiento realmente necesitan un analizador completo para poder interpretarlo correctamente.
Tenga en cuenta que la sensibilidad de mayúsculas y minúsculas deberá desactivarse para responder a la pregunta tal como se establece. En perl, ese es el modificador i :
$ echo "Data Data Data [Start] Data i want [End] Data" /
| perl -ne ''//[start/](.*?)/[end/]/i; print "$1/n"''
Data i want
El otro truco es usar el *? cuantificador que desactiva la codicia de la pareja capturada. Por ejemplo, si tiene una etiqueta [final] no coincidente:
Data Data [Start] Data i want [End] Data [end]
probablemente no quieras capturar:
Data i want [End] Data
Si bien puede usar una expresión regular para analizar los datos entre las etiquetas de apertura y cierre, necesita pensar detenidamente si esta es una ruta que desea bajar. La razón de esto es el potencial de las etiquetas para anidar: si las etiquetas de anidación podrían ocurrir alguna vez, el lenguaje ya no es regular y las expresiones regulares dejan de ser la herramienta adecuada para analizarlo.
Muchas implementaciones de expresiones regulares, como PCRE o las expresiones regulares de perl, admiten el rastreo posterior que se puede utilizar para lograr este efecto aproximado. Pero PCRE (a diferencia de perl) no es compatible con backtracking ilimitado, y esto puede hacer que las cosas se rompan de manera extraña tan pronto como tenga demasiadas etiquetas.
Hay una publicación de blog muy comúnmente citada que analiza esto más, http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html (google para ello y verifique la caché actualmente, parece que están teniendo algún tiempo de inactividad)
$text ="Data Data Data start Data i want end Data";
($content) = $text =~ m/ start (.*) end /;
print $content;
Tuve un problema similar por un tiempo y puedo decirle que este método funciona ...
/[start/](.*?)/[end/]
Zhich pondrá el texto en el medio dentro de una captura.
/[start/]/s*(((?!/[start/]|/[end/]).)+)/s*/[end/]
Esto debería arrojar los marcadores [start]
y [end]
también.