У меня есть файл в следующем формате:
Данные Данные Данные [Начните] Данные я хочу [Конец] Данные
Я хотел бы, чтобы захватить Data I want
с между [Start]
и [End]
тегами с помощью Regex. Кто-нибудь может показать мне, как это можно сделать?
\[start\]\s*(((?!\[start\]|\[end\]).)+)\s*\[end\]
Это следует надеяться , опускать [start]
и [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#How_do_I_find_matchi . В частности, имейте в виду, что для правильной интерпретации вложенных тегов действительно необходим полноценный синтаксический анализатор.
Обратите внимание, что чувствительность к регистру нужно будет отключить, чтобы ответить на поставленный вопрос. В 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
}
Обратитесь к этому вопросу, чтобы вытянуть текст между тегами с пробелами и точками ( .
)
[\S\s]
это тот, который я использовал
Регулярное выражение для соответствия любому символу, включая новые строки
Чтение текста с помощью квадратных скобок [], т. Е. [Start] и [End], и проверка массива списком значений. 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;
}