1 / 1 / 0
Регистрация: 31.03.2017
Сообщений: 47
1

Вложеное регулярное выражение

31.03.2017, 05:34. Показов 2241. Ответов 14

Author24 — интернет-сервис помощи студентам
Допустим есть строка вида:

HTML5
1
<p>привет</p> &p_not& <p>привет1</p> <p>привет2</p> &p_not& <p>привет10</p>
Можно ли как то составить регулярное выражение чтобы удалить все теги <p> и </p> заключенные между &p_not& (удалить вместе с &p_not&), но при этом оставить <p> и </p> которые не входят в "скобки" &p_not&? Текст может быть очень длинным и "скобок" &p_not& может быть не одна. Есть ли вообще такая возможность?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.03.2017, 05:34
Ответы с готовыми решениями:

Регулярное выражение из командной строки
Всем привет! Сильно не пинайте, я в perl только начал разбираться, да и в регулярных выражениях...

Регулярное выражение, поиск последнего вхождения
Всем привет. Подскажите, пожалуйста, регулярное выражение для поиска последнего вхождения в...

Регулярное выражение: содержит ли строка текст, соответствующий шаблону K-00000000
Коллеги, нужен небольшой хелп. нужно проверить, содержит ли строка текст соответствующий шаблону...

Написать регулярное выражение для выделения из строки только одного числа на определённой позиции
Товарищи, подскажите! Как написать рег. выражение для выделения из строки только одного числа на...

14
5925 / 1968 / 321
Регистрация: 10.12.2013
Сообщений: 6,801
31.03.2017, 08:07 2
Perl
1
s/((&p_not&).+\2)//mg
0
1 / 1 / 0
Регистрация: 31.03.2017
Сообщений: 47
31.03.2017, 09:55  [ТС] 3
А разве это не удалит и все что находиться между <p>?
0
352 / 222 / 25
Регистрация: 30.09.2012
Сообщений: 548
31.03.2017, 10:36 4
Попробуйте так
Perl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!perl
 
use strict;
use warnings;
 
my $txt = '<p>привет</p> &p_not& <p>привет1</p> <p>привет2</p> &p_not& <p>привет10</p> &p_not& <p>привет1</p> <p>привет2</p> &p_not& <p>привет11</p>';
 
$txt =~ s/((&p_not&)(.+?)\2)/@{[func($3)]}/mg;
 
print "$txt\n";
 
sub func {
    my $txt = shift;
    $txt =~ s/<\/?p>//mg;
    return $txt;
}
Удачи
0
5925 / 1968 / 321
Регистрация: 10.12.2013
Сообщений: 6,801
31.03.2017, 10:38 5
Лучший ответ Сообщение было отмечено zhukovia как решение

Решение

пожалуй, от регулярной жадности неплохо бы избавиться;
добавил `?` к `.+`.

проверь.
Bash
1
perl -0pe 's/((&p_not&).+?\2)//mg' test.html
1
1 / 1 / 0
Регистрация: 31.03.2017
Сообщений: 47
31.03.2017, 12:36  [ТС] 6
Большое спасибо. Это то что нужно.
0
1 / 1 / 0
Регистрация: 31.03.2017
Сообщений: 47
01.04.2017, 14:20  [ТС] 7
Извините, немного поторопился с ответом. Вообщем это не то. Получается
HTML5
1
<p>hello</p>  <p>hello10</p>
а надо
HTML5
1
<p>привет</p> привет1 привет2 <p>привет10</p>
Т.е. надо убрать теги (а не сами слова) у тех слов что находятся внутри &p_not&. Такое можно реализовать?
0
5925 / 1968 / 321
Регистрация: 10.12.2013
Сообщений: 6,801
02.04.2017, 13:44 8
Лучший ответ Сообщение было отмечено zhukovia как решение

Решение

ну, например можно так, как предложил pka в #4

добавить модификатор e и в заменяющую часть subst вставить ещё один subst,
холодно удаляющий все тэги из захваченного $2:
Bash
1
perl -0pe 's {(&p_not&)(.+?)\1} { $2 =~ s [</?\w+>] []rg }mge' test.html
0
1 / 1 / 0
Регистрация: 31.03.2017
Сообщений: 47
03.04.2017, 08:26  [ТС] 9
Цитата Сообщение от volodin661 Посмотреть сообщение
ну, например можно так, как предложил pka в #4
Попробую так когда доберусь до базы.

Цитата Сообщение от volodin661 Посмотреть сообщение
добавить модификатор e и в заменяющую часть subst вставить ещё один subst,
холодно удаляющий все тэги из захваченного $2:
Bash
1
perl -0pe 's {(&p_not&)(.+?)\1} { $2 =~ s [</?\w+>] []rg }mge' test.html
А так выдает ошибку. Если я правильно понял то он не может понять что за переменная $2. А разве можно подобную конструкцию ($2 =~ s [</?\w+>] []rg) запихать во вторую часть s//?
Кликните здесь для просмотра всего текста
Bareword found where operator expected at -e line 1, near "s [</?\w+>] []rg"
(Do you need to predeclare s?)
syntax error at -e line 1, near "s [</?\w+>] []rg "
Execution of -e aborted due to compilation errors.


Добавлено через 42 минуты
Цитата Сообщение от pka Посмотреть сообщение
Попробуйте так
Perl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!perl
 
use strict;
use warnings;
 
my $txt = '<p>привет</p> &p_not& <p>привет1</p> <p>привет2</p> &p_not& <p>привет10</p> &p_not& <p>привет1</p> <p>привет2</p> &p_not& <p>привет11</p>';
 
$txt =~ s/((&p_not&)(.+?)\2)/@{[func($3)]}/mg;
 
print "$txt\n";
 
sub func {
    my $txt = shift;
    $txt =~ s/<\/?p>//mg;
    return $txt;
}
Удачи
Работает но почему то только для одной строки. Если в файле есть несколько строк то делается только первая. Подскажите, пожалуйста, как сделать для нескольких строк, куда \r\n засунуть? И &p_not& могут находиться в разных строках (открытие-закрытие)
0
5925 / 1968 / 321
Регистрация: 10.12.2013
Сообщений: 6,801
03.04.2017, 09:45 10
Цитата Сообщение от zhukovia Посмотреть сообщение
А так выдает ошибку. Если я правильно понял то он не может понять что за переменная $2.
Он может. И залогом этого является обрамление выражения круглыми скобками в шаблонной части составного оператора s ( substitute).

Цитата Сообщение от zhukovia Посмотреть сообщение
А разве можно подобную конструкцию ($2 =~ s [</?\w+>] []rg) запихать во вторую часть s//?
Можно. Сгодится любое выражение Perl.

Я проверяю на нескольких OS свои советы перед публикацией.
Этот был проверен на MacOS, Windows XP, Windows 10.
Для работы в ком. строке Windows следует заменить одинарные кавычки на двойные.

Приведи здесь вывод команды
Bash
1
perl -V
для проверки источника подозрительной ругани про bareword
(Bareword found where operator expected at -e line 1, near "s [</?\w+>] []rg")

Можешь также убрать пробелы при оформлении оператора s, чтобы не дразнить гусей.
Bash
1
perl -0pe 's{(&p_not&)(.+?)\1}{ $2 =~ s[</?\w+>][]rg }mge' test.html
Добавлено через 8 минут
да, и во вложенном subst надо тоже применить модификатор m(multiple lines), вот так:
Bash
1
perl -0pe 's{(&p_not&)(.+?)\1}{ $2 =~ s[</?\w+>][]mrg }mge' test.html
0
1 / 1 / 0
Регистрация: 31.03.2017
Сообщений: 47
03.04.2017, 15:36  [ТС] 11
Цитата Сообщение от volodin661 Посмотреть сообщение
Приведи здесь вывод команды
Bash
1
perl -V
Я это делаю на Linux CentOS
Кликните здесь для просмотра всего текста

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Summary of my perl5 (revision 5 version 10 subversion 1) configuration:
   
  Platform:
    osname=linux, osvers=2.6.32-220.el6.x86_64, archname=i386-linux-thread-multi
    uname='linux c6b8.bsys.dev.centos.org 2.6.32-220.el6.x86_64 #1 smp tue dec 6 19:48:22 gmt 2011 i686 i686 i386 gnulinux '
    config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -DDEBUGGING=-g -Dversion=5.10.1 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib/perl5 -Dprivlib=/usr/share/perl5 -Darchlib=/usr/lib/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Dvendorarch=/usr/lib/perl5/vendor_perl -Dinc_version_list=5.10.0 -Darchname=i386-linux-thread-multi -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.4.7 20120313 (Red Hat 4.4.7-16)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=/lib/libc-2.12.so, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.12'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib/perl5/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables -L/usr/local/lib'
 
 
Characteristics of this binary (from libperl): 
  Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV
                        PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP USE_ITHREADS
                        USE_LARGE_FILES USE_PERLIO USE_REENTRANT_API
                        USE_SITECUSTOMIZE
  Built under linux
  Compiled at Nov 10 2015 11:51:08
  @INC:
    /usr/local/lib/perl5
    /usr/local/share/perl5
    /usr/lib/perl5/vendor_perl
    /usr/share/perl5/vendor_perl
    /usr/lib/perl5
    /usr/share/perl5
    .


Добавлено через 3 минуты
Цитата Сообщение от volodin661 Посмотреть сообщение
Добавлено через 8 минут
да, и во вложенном subst надо тоже применить модификатор m(multiple lines), вот так:
Bash
1
perl -0pe 's{(&p_not&)(.+?)\1}{ $2 =~ s[</?\w+>][]mrg }mge' test.html
Все равно не заработало. Только теперь.
Bash
1
2
3
4
[root@lserver ~]# perl -0pe 's{(&p_not&)(.+?)\1}{$2=~s[</?\w+>][]mrg}mge'
Bareword found where operator expected at -e line 1, near "s[</?\w+>][]mrg"
syntax error at -e line 1, near "s[</?\w+>][]mrg"
Execution of -e aborted due to compilation errors.
0
5925 / 1968 / 321
Регистрация: 10.12.2013
Сообщений: 6,801
04.04.2017, 05:35 12
м-да..
модификатор r(readonly) появился только в Perl 5.14,
поэтому вот так:
Perl
1
perl -0pe 's {(&p_not&)(.+?)\1} { ($x=$2) =~ s [</?\w+>] []mg; $x }mge' test.html
1
1 / 1 / 0
Регистрация: 31.03.2017
Сообщений: 47
04.04.2017, 10:45  [ТС] 13
Цитата Сообщение от volodin661 Посмотреть сообщение
Perl
1
perl -0pe 's {(&p_not&)(.+?)\1} { ($x=$2) =~ s [</?\w+>] []mg; $x }mge' test.html
Спасибо, этот вариант рабочий. Только вскрылся ещё один неприятный момент про который я сразу не подумал. Оказывается если &p_not& находятся не в одной строке то удаления не происходит, а у меня как раз может находится где угодно. Если это возможно то переделайте его чтобы работало и в разных строках (тэги <p> и </p> тоже не в одной строке обычно). Или скажите тогда правильно ли я понял как это работает, попробую сам разобраться.
1. Фигурные скобки и квадратные - это вместо s//. Так как вложенные выражения и нельзя поставить s//
2. (&p_not&)(.+?)\1 это тоже самое что и (&p_not&)(.+?)(&p_not&)
3. ($x=$2) =~ s здесь мы присваиваем переменной $x $2 (из левой части то что находиться между &p_not&) и делаем поиск с заменой.
4. Не совсем понял зачем мы в конце после ; пишем $x
5. [</?\w+>] [] здесь ищем <любая буква> и </любая буква> и удаляем их.
Правильно?
Я полагаю что в (&p_not&)(.+?)\1 нужно дописать, что-то типа [\r|\n|\s]* Вот только не понятно куда.
0
5925 / 1968 / 321
Регистрация: 10.12.2013
Сообщений: 6,801
04.04.2017, 17:41 14
Лучший ответ Сообщение было отмечено zhukovia как решение

Решение

Цитата Сообщение от zhukovia Посмотреть сообщение
Оказывается если &p_not& находятся не в одной строке то удаления не происходит,
да просто добавить модификатор s
Bash
1
perl -0pe 's {(&p_not&)(.+?)\1} { ($x=$2) =~ s [</?\w+>] []mgs; $x }mgse' test.html
1
1 / 1 / 0
Регистрация: 31.03.2017
Сообщений: 47
05.04.2017, 05:45  [ТС] 15
Цитата Сообщение от volodin661 Посмотреть сообщение
да просто добавить модификатор s
Bash
1
perl -0pe 's {(&p_not&)(.+?)\1} { ($x=$2) =~ s [</?\w+>] []mgs; $x }mgse' test.html
Огромное спасибо. Теперь получилось. Только надо немного умерить жадность или прямо прописать. А то у меня поудалялись и все другие теги в скобках &p_not&. Вместо
Bash
1
[</?\w+>]
поставил явно
Bash
1
[</?p>]
Еще раз спасибо за терпение.
0
05.04.2017, 05:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.04.2017, 05:45
Помогаю со студенческими работами здесь

регулярное выражение
как обрезать строку до символов &quot; |&quot;? спасибо

Регулярное выражение
Здравствуйте!!!На дом задали ознакомиться с регулярными выражениями на Perl....понимаю, что никто...

Регулярное выражение
Есть регулярка, которая отыскивает в строке запись часла с экспонентной Нужно заменить на число в...

Регулярное выражение
есть файл: &lt;body lang=3DRU link=3Dblue = vlink=3Dpurple&gt;&lt;div class=3DWordSection1&gt;&lt;p =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru