Регулярное выражение:Чтобы вытащить подстроку между двумя тегами в строке

StackOverflow https://stackoverflow.com/questions/1237

  •  08-06-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

\[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#How_do_I_find_matchi.В частности, имейте в виду, что вложенным тегам действительно нужен полноценный синтаксический анализатор для правильной интерпретации.

Обратите внимание, что для того, чтобы ответить на поставленный вопрос, необходимо отключить чувствительность к регистру.В Perl это я модификатор:

$ echo "Data Data Data [Start] Data i want [End] Data" \
  | perl -ne '/\[start\](.*?)\[end\]/i; print "$1\n"'
 Data i want 

Другой трюк заключается в использовании *? квантор, который отключает жадность захваченного совпадения.Например, если у вас есть несовпадающий [конец] ярлык:

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] это тот, который я использовал

Regex для соответствия любому символу, включая новые строки

Чтение текста с квадратными скобками [], т. е. [Начало] и [Конец], и проверка массива со списком значений. 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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top