Regex: вытащить подстроку между двумя тегами в строке

У меня есть файл в следующем формате:

Data Data
Data
[Start]
Data I want
[End]
Data

Я хотел бы захватить Data I want между тегами [Start] и [End] с помощью Regex. Может ли кто-нибудь показать мне, как это можно сделать?

Ответ 1

\[start\]\s*(((?!\[start\]|\[end\]).)+)\s*\[end\]

Это, вероятно, должно оставить маркеры [start] и [end].

Ответ 2

\[start\](.*?)\[end\]

Чжич поместит текст посередине в пределах захвата.

Ответ 3

$text ="Data Data Data start Data i want end Data";
($content) = $text =~ m/ start (.*) end /;
print $content;

У меня была аналогичная проблема некоторое время, и я могу сказать, что этот метод работает...

Ответ 4

Более полное обсуждение ловушек использования регулярных выражений для поиска совпадающих тегов можно найти по адресу: 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

Ответ 5

В то время как вы можете использовать регулярные выражения для разбора данных между открывающим и закрывающим тегами, вам нужно долго и упорно думать как ли это путь, который вы хотите идти вниз. Причина этого в том, что потенциал тегов заключается в гнезде: если теги вложенности могут когда-либо произойти или когда-либо произойдут, говорят, что язык больше не является регулярным, а регулярные выражения перестают быть подходящим инструментом для его синтаксического анализа.

Многие реализации регулярных выражений, такие как регулярные выражения PCRE или perl, поддерживают обратное отслеживание, которое можно использовать для достижения этого грубого эффекта. Но PCRE (в отличие от perl) не поддерживает неограниченное обратное отслеживание, и это может на самом деле заставить вещи сломаться странными способами, как только у вас слишком много тегов.

Там очень часто цитируется сообщение в блоге, в котором обсуждается это больше, http://kore-nordmann.de/blog/do_NOT_parse_using_regexp.html (google для него и проверить кеш в настоящее время, кажется чтобы иметь некоторый простой)

Ответ 6

Хорошо, если вы гарантируете, что за каждым начальным тегом следует конечный тег, тогда будет работать следующее.

\[start\](.*?)\[end\]

Однако, если у вас есть сложный текст, например:

[start] sometext [start] sometext2 [end] sometext [end]

тогда у вас возникнут проблемы с регулярным выражением.

Теперь следующий пример вытащит все горячие ссылки на странице:

'/<a(.*?)a>/i'

В приведенном выше случае мы можем гарантировать, что не было бы никаких вложенных случаев:

'<a></a>'

Итак, это сложный вопрос и не может быть просто решен простым ответом.

Ответ 7

С помощью 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
}

Ответ 9

Чтение текста в квадратных скобках [], т.е. [Начало] и [Конец], и проверка массива со списком значений. 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;
}