Регулярное выражение: вытащить подстроку между двумя тегами в строке - PullRequest
44 голосов
/ 04 августа 2008

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

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

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

Ответы [ 9 ]

63 голосов
/ 04 августа 2008
\[start\](.*?)\[end\]

Жич поместит текст посередине в кадре.

23 голосов
/ 04 августа 2008
\[start\]\s*(((?!\[start\]|\[end\]).)+)\s*\[end\]

Надеемся, что это также приведет к падению маркеров [start] и [end].

5 голосов
/ 06 октября 2012
$text ="Data Data Data start Data i want end Data";
($content) = $text =~ m/ start (.*) end /;
print $content;

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

4 голосов
/ 15 сентября 2008

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

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

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

4 голосов
/ 20 августа 2008

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

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

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

Однако, если у вас сложный текст, такой как следующий:

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

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

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

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

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

'<a></a>'

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

1 голос
/ 04 августа 2008

С 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
}
0 голосов
/ 12 сентября 2014

Чтение текста с помощью квадратных скобок [], т. Е. [Начало] и [Конец] и проверка массива со списком значений. 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;
}
0 голосов
/ 29 августа 2013

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

[\S\s] это тот, который я использовал

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...