2015-03-03 3 views
-1

Следующие регулярные выражения работают, но может ли кто-нибудь объяснить, как? Любые комментарии оцениваются! Благодаря! QuinoaЧто происходит внутри этого выражения для изменения регулярного выражения

Что такое регулярное выражение "|" делая, чтобы стричь теги "" и "" от <script>Keep THIS</Script>, чтобы получить "Keep THIS" в память $ 1?

Вот REGEX:

(?x) 
([\w\.!?,\s-])|<.*?>|. 

Вот строка:

<script>Keep THIS</Script> 

Результаты: $ 1 = "Keep ЭТА"

комментарии ниже:

(?x)      set flags for this block (disregarding 
          whitespace and comments) (case-sensitive) 
          (with^and $ matching normally) (with . 
          not matching \n) 

    (      group and capture to \1: 
    [\w\.!?,\s-]    any character of: word characters (a-z, 
          A-Z, 0-9, _), '\.', '!', '?', ',', 
          whitespace (\n, \r, \t, \f, and " "), '- 
          ' 
)      end of \1 
|      OR 
    <      '<' 
    .?      any character except \n (optional 
          (matching the most amount possible)) 
    >      '>' 
|      OR 
    .      any character except \n 
+0

Вот строка с тегами, используемыми в примере: '""' – quinoa

+0

Пожалуйста, всегда * покажите свой код Perl. Существует множество способов комбинировать компоненты, которые вы показали. – Borodin

ответ

1

<.*?> соответствует всем тегам, то есть соответствует всем строкам, начинающимся с < и заканчивается >. Затем из оставшейся строки это регулярное выражение ([\w\.!?,\s-]) будет захватывать весь символ слова или точку или ! или ? или пробел, запятую или дефис. Обратите внимание, что он будет захватывать каждый отдельный символ в группе 1.

Если вы хотите захватить целую строку Keep THIS в группу 1, то вам нужно добавить квант + рядом с классом символов. + повторяет предыдущий токен один или несколько раз.

([\w\.!?,\s-]+)|<.*?>|. 

Наконец . соответствует всем остальным символам, которые не удовлетворяют заданные условие.

DEMO

+0

Спасибо Авинаш за быстрый ответ! Вы говорите, что есть порядок соответствия? Начинается ли порядок справа от периода до последнего «|»? 1. Первое совпадение - '"|."', Которое представляет собой целую строку, 2. Второе совпадение - это теги и 3. Третье соответствие - это оставшаяся строка. – quinoa

+0

Сначала '([\ w \.!?, \ S -] +)' соответствует всем символам слова, пробелам и т. Д., Кроме '<', '>'. Затем после того, как он видит шаблон '<.*?>', он соответствует строкам тега, оставив только оставшуюся между ними строку 'Keep THis'. Но я всегда предлагаю вам написать '<.*?> | ([\ w \.!?, \ S -]) | .'. Наконец. соответствует всем оставшимся символам, которые не совпадают. –

+0

NOte, что двигатель регулярных выражений анализирует строку слева направо. –

0

Единственный способ это делает то, что вы говорите, если вы используете глобальный матч в цикле, и не use warnings на месте, как вы должны.

Вот что я думаю, что вы имеете, но используя Data::Dump для отображения содержимого $1 вместо того, что предположительно print $1 в вашем собственном коде. (Это действительно помогает много, чтобы показать свой реальный код Perl вместо отдельных фрагментов.)

use strict; 
use warnings; 

use Data::Dump; 

my $s = '<script>Keep THIS</Script>'; 

my $re = qr/(?x) 
([\w\.!?,\s-])|<.*?>|./; 

while ($s =~ /$re/g) { 
    dd $1; 
} 

выход

undef 
"K" 
"e" 
"e" 
"p" 
" " 
"T" 
"H" 
"I" 
"S" 
undef 
  • Первый проход соответствие <script>, который ISN 't снято так $1 не определено.
  • Последующие проходы соответствуют одному символу из класса [\w\.!?,\s-], который потребляет строку Keep THIS по одному символу за раз.
  • И наконец, закрытие </Script> согласовано без фиксации, а также оставляет $1 не определено снова.

undef печатается как пустая строка, и без warnings включен, то вы не будете предупреждены к нему.

Решение всегда использует парсер HTML-парсер для обработки HTML. Регулярные выражения являются неправильным инструментом для работы.