2008-08-04 1 views
41

У меня есть файл в следующем формате:Regex: Для того, чтобы вытащить подстроку между двумя тегами в строке

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

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

+1

похож на "RegEx получить текст в тегах" - http://stackoverflow.com/questions/353309/regex-to-get-text-within-tags – 2008-12-09 16:56:06

ответ

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

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

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

Zhich'll положил текст посередине в пределах захвата.

+2

Намного лучше (проще), чем принятый ответ ... :-) – PhiLho 2008-12-09 17:34:52

+6

Это еще не поймает строки, которые имеют разрывы строк – Doug 2010-04-19 03:22:42

1

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

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

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

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

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

3

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

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

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

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

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

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

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

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

'<a></a>' 

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

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

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

0

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