Регулярное выражение: вытащить подстроку между двумя тегами в строке
У меня есть файл в следующем формате:
Данные Данные Данные [Начните] Данные я хочу [Конец] Данные
Я хотел бы взять Data I want
между [Start]
а также [End]
теги с использованием регулярных выражений. Кто-нибудь может показать мне, как это можно сделать?
9 ответов
\[start\]\s*(((?!\[start\]|\[end\]).)+)\s*\[end\]
Надеемся, это [start]
а также [end]
маркеры тоже.
\[start\](.*?)\[end\]
Жич поместит текст посередине в кадре.
$text ="Data Data Data start Data i want end Data";
($content) = $text =~ m/ start (.*) end /;
print $content;
Некоторое время у меня была похожая проблема, и я могу сказать вам, что этот метод работает...
Более полное обсуждение ловушек использования регулярных выражений для поиска подходящих тегов можно найти по адресу: http://faq.perl.org/perlfaq4.html. В частности, имейте в виду, что для правильной интерпретации вложенных тегов действительно необходим полноценный синтаксический анализатор.
Обратите внимание, что чувствительность к регистру нужно будет отключить, чтобы ответить на поставленный вопрос. В Perl это модификатор i:
$ echo "Data Data Data [Start] Data i want [End] Data" \
| perl -ne '/\[start\](.*?)\[end\]/i; print "$1\n"'
Data i want
Другой трюк заключается в использовании *? квантификатор, который отключает жадность захваченного матча. Например, если у вас есть несоответствующий тег [end]:
Data Data [Start] Data i want [End] Data [end]
Вы, вероятно, не хотите захватывать:
Data i want [End] Data
Несмотря на то, что вы можете использовать регулярное выражение для анализа данных между открывающими и закрывающими тегами, вы должны долго и усердно задумываться о том, следует ли идти по этому пути. Причиной этого является возможность вложения тегов: если вложение тегов может произойти или может произойти, говорят, что язык больше не является регулярным, и регулярные выражения перестают быть подходящим инструментом для его анализа.
Многие реализации регулярных выражений, такие как PCRE или регулярные выражения perl, поддерживают возврат, который можно использовать для достижения этого грубого эффекта. Но PCRE (в отличие от Perl) не поддерживает неограниченный возврат, и это может фактически привести к непредсказуемым последствиям, как только у вас будет слишком много тегов.
Существует очень часто цитируемое сообщение в блоге, в котором обсуждается это более подробно, http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html (поищите в Google и проверьте кеш в настоящее время, похоже, у них некоторое время простоя)
Что ж, если вы гарантируете, что за каждым начальным тегом следует конечный тег, то сработает следующее.
\[start\](.*?)\[end\]
Однако, если у вас сложный текст, такой как следующий:
[start] sometext [start] sometext2 [end] sometext [end]
тогда вы столкнетесь с проблемами с регулярным выражением.
Теперь следующий пример вытянет все горячие ссылки на странице:
'/<a(.*?)a>/i'
В приведенном выше случае мы можем гарантировать, что не будет никаких вложенных случаев:
'<a></a>'
Итак, это сложный вопрос, и его нельзя решить простым ответом.
С помощью Perl вы можете окружать нужные данные с помощью () и извлекать их позже, возможно, другие языки имеют аналогичную функцию.
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
}
Чтение текста в квадратных скобках [], т. Е.[Начало] и [Конец], и проверка массива со списком значений. 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;
}
Обратитесь к этому вопросу, чтобы вытащить текст между тегами с пробелами и точками (.
)
[\S\s]
это тот, который я использовал
Регулярное выражение для соответствия любому символу, включая новые строки