[Регулярки & Mod_Rewrite] Задай вопрос, получи ответ

Discussion in 'Общие вопросы программирования' started by Kaimi, 7 May 2015.

  1. Kaimi

    Kaimi Well-Known Member

    Joined:
    23 Aug 2007
    Messages:
    1,732
    Likes Received:
    811
    Reputations:
    231
    Продолжение темы: https://forum.antichat.ru/threads/92492/
     
    _________________________
  2. truelamer

    truelamer Elder - Старейшина

    Joined:
    6 Nov 2007
    Messages:
    135
    Likes Received:
    30
    Reputations:
    5
    Дорого времени суток, не могу осилить одно регулярное выражение, надеюсь на вашу помощь.

    использую в wordpress следующую стандартную функцию для добавления правила для ЧПУ:

    Code:
    add_rewrite_rule(
    'magazin/([^/]+)/([^p][^a][^g][^e]*)(/page/([0-9]+)?)?/?$',
      'index.php?taxonomy=magazin&term=$matches[1]&bbbb=$matches[2]&paged=$matches[4]'
    , 'top' );
    у меня исходные ссылки вида http://site.ru/magazin/kategotiya/любое/количество/параметров/через/слеш/page/2/

    НЕ получается вытащить параметры между категорией и пагинацией. Выше описанное решение работает но как только попадается вторая буква 'е' то все падает, уже как только не пробовал.
     
  3. b3

    b3 Banned

    Joined:
    5 Dec 2004
    Messages:
    2,174
    Likes Received:
    1,157
    Reputations:
    202
    Я ничего не понял про вторую букву "Е" но как вариант указать квантификатор {1} на данную букву.

    Я так понял речь об этой части правила?
     
  4. InfectedM

    InfectedM Elder - Старейшина

    Joined:
    4 Nov 2007
    Messages:
    155
    Likes Received:
    12
    Reputations:
    0
    строка: [title]Всем привет![\title]

    помогите спарсить по нормальному между [title] и [\title]
    не могу понять как подставить обратный слэш, в интернете написано что это два слеша, но у меня почему-то не работает(


    так не работает:
    preg_match_all("/\[title\](.+?)\[\\title\]/", $content, $matches1);
    сделал говно кодом:
    preg_match_all("/\[title\](.+?)\[.+title\]/", $content, $matches1);
     
  5. InfectedM

    InfectedM Elder - Старейшина

    Joined:
    4 Nov 2007
    Messages:
    155
    Likes Received:
    12
    Reputations:
    0

    делаю так:
    preg_match_all("/\[title\](.+?)\[\\\\title\]\[info\](.+?)\[\\\\info\]\[demo\](.+?)\[\\\\demo\]\[download\](.+?)\[\\\\download\]/", $content, $matches1);


    не работает почему-то.


    а если без downlod :
    preg_match_all("/\[title\](.+?)\[\\\\title\]\[info\](.+?)\[\\\\info\]\[demo\](.+?)\[\\\\demo\]/", $content, $matches1);

    то все ок.
    в чем косяк, подскажите плиз?
     
  6. Rado

    Rado Elder - Старейшина

    Joined:
    30 May 2011
    Messages:
    281
    Likes Received:
    289
    Reputations:
    39
    Если я правильно понял что тебе надо, то (?<=title]).*(?=\[\\title)
    С твоего текста вытянет [Nulled] Yoast SEO Premium v2.2.2
     
  7. InfectedM

    InfectedM Elder - Старейшина

    Joined:
    4 Nov 2007
    Messages:
    155
    Likes Received:
    12
    Reputations:
    0
    Спасибо, о не знал про существование этих штук.
    (?<=title]).*(?=\[\\title)





    почитал в вики про них, полезная штука.
     
    #7 InfectedM, 30 Jul 2015
    Last edited: 30 Jul 2015
  8. InfectedM

    InfectedM Elder - Старейшина

    Joined:
    4 Nov 2007
    Messages:
    155
    Likes Received:
    12
    Reputations:
    0
    Движок WP
    категория выглядит так : site.ru/porno-flash/
    подкатегория: site.ru/porno-flash/podcat/
    Сменил название категории на site.ru/porno-igry


    Помогите плиз, нужно осуществить редиректы
    делаю вот так:

    RewriteRule porno-flash/$ porno-igry/ [R=301,L]
    RewriteRule porno-flash/bdsm/$ porno-igry/bdsm/ [R=301,L]
    RewriteRule porno-flash/milf/$ porno-igry/milf/ [R=301,L]

    Но работает очень криво, допусим захожу на porno-igry/bdsm/ , а он меня вообще перекидывает не на раздел а на конкретную игру, где есть вхождение bdsm.
     
  9. Грабитель

    Joined:
    5 Mar 2013
    Messages:
    196
    Likes Received:
    12
    Reputations:
    -7
    Помогите составить регулярку, которой можно дернуть всё что в рамках HTML тегов: <div name="test"> some text <div name="some tag"> some text</div> some text </div>
    Проблема заключается во вложенности между целевыми тегами <div> сколь угодно аналогичных тегов <div> правда с другими названиями.

    То есть, начальное вхождение: <div name="some tag"> - неизменное, и встречается в тексте один раз. Начиная с него надо дернуть весь текст который находится в рамках тега <div name="some tag"> и соответствующему ему закрывающемуся тегу </div> (именно тегу <div name="some tag">, а не первый попавшийся тег </div>)

    Буду благодарен, если кто поможет с регуляркой.
     
  10. Fepsis

    Fepsis Elder - Старейшина

    Joined:
    17 Sep 2008
    Messages:
    791
    Likes Received:
    391
    Reputations:
    72
    Как правило, после нужного </div> можно найти что-то, что будет служить признаком того, что это именно нужный тебе див закрылся. Ну или решать вопрос парсером DOM.
     
  11. Грабитель

    Joined:
    5 Mar 2013
    Messages:
    196
    Likes Received:
    12
    Reputations:
    -7
    1) после нужного </div> "что-то" не найти.
    2) парсер DOM не может выдернуть всё что между тегами, только текст без самих тегов, обсуждалось уже в соседней теме про php
    Вопрос актуален, буду признателен за помощь.
     
  12. alex2523

    alex2523 Member

    Joined:
    10 May 2015
    Messages:
    12
    Likes Received:
    13
    Reputations:
    1
    За PHP не скажу, на Python lxml умеет искать в DOM по xpath, включая атрибуты <div>, с извлечением innerHTML нет проблем.
    Приблизительный Python код:
    Code:
    import lxml
    from lxml import etree
    import lxml.html
    import re
    
    HTML = """<div name="test"> some text <div name="some tag"> some text</div> some text </div>"""
    utf8_parser = lxml.html.HTMLParser(encoding='utf-8')
    parser = lxml.html.document_fromstring(HTML, parser=utf8_parser)
    
    elements = parser.xpath('//div[@name="test"]')
    div = elements[0]
    
    str_div = etree.tostring(div)
    div_HTML = re.sub(r'^<div[^>]+>(.*)</div>$', r"\1", str_div, re.DOTALL)
    print div_HTML
    
    # output:  some text <div name="some tag"> some text</div> some text
    
    С PHP особо не знаком, в принципе тоже должен существовать DOM-парсер на PHP с поиском по xpath, его результат преобразуется в HTML - и далее регуляркой вырезать сам innerHTML без дива. Только регекспом здесь не получится вырезать, разве что какой-нить упоротый perl ninja-фанат однострочников такое осилит, в ущерб читабельности и понимабельности.
     
    #12 alex2523, 21 Sep 2015
    Last edited: 21 Sep 2015
    Грабитель likes this.
  13. hesher

    hesher Elder - Старейшина

    Joined:
    23 Aug 2005
    Messages:
    74
    Likes Received:
    108
    Reputations:
    4
    <div name="home"><div name="test"><div name="some tag2"> some text some<div name="some tag1">fsa</div> text</div> some text </div></div>

    PHP:
    $divs '@<div\s+name="test"\s*>((?:(?:(?!<div[^>]*>|</div>).)++|<div[^>]*>(?1)</div>)*)</div>@si';
    preg_match_all($divs$html$result);
    Array
    (
    [0] => Array
    (
    [0] => <div name="test"><div name="some tag2"> some text some<div name="some tag1">fsa</div> text</div> some text </div>
    )

    [1] => Array
    (
    [0] => <div name="some tag2"> some text some<div name="some tag1">fsa</div> text</div> some text
    )

    )
    [Finished in 0.1s]
     
    Fepsis and Грабитель like this.
  14. Грабитель

    Joined:
    5 Mar 2013
    Messages:
    196
    Likes Received:
    12
    Reputations:
    -7
    hesher большое спасибо, то что нужно!
     
  15. coolhacker77

    coolhacker77 New Member

    Joined:
    11 Jan 2008
    Messages:
    7
    Likes Received:
    1
    Reputations:
    0
    Всем доброго времени! Очень рассчитываю на вашу помощь)

    В директории:

    http://site.ru/wp-content/plugins/seo/

    лежат файлы вида odin-dva.php

    Хочу выводить их от корня и без .php, чтоб все было вида:

    http://site.ru/odin-dva/

    Для этого использую код для htaccess:

    HTML:
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*).php$ wp-content/plugins/seo/$1.php [L,QSA]
    </IfModule>

    В итоге файлы от корня работают, но с расширением .php и все внутренние ссылки блога перестают работать выдавая 404
    Где я ошибся?
     
  16. t0ma5

    t0ma5 Reservists Of Antichat

    Joined:
    10 Feb 2012
    Messages:
    829
    Likes Received:
    815
    Reputations:
    90
    столкнулся сегодня с таким поведением группы символов \w , проще будет показать код

    Code:
    
    123@123:~$ cat 1.pl
    $a = "qwerwe\n";
    unless($a=~/^[\w]+$/)
    {
        print "no";
    }
    else
    {
        print "yes";
    }
    123@123:~$ perl 1.pl
    yes
    
    то есть пропускает символ переноса строки \n, причем два символа не пропускает

    Code:
    
    123@123:~$ cat 1.pl
    $a = "qwerwe\n\n";
    unless($a=~/^[\w]+$/)
    {
        print "no";
    }
    else
    {
        print "yes";
    }
    123@123:~$ perl 1.pl
    no
    
    погуглив маны толком информации не нашел, везде пишут что \w это [0-9a-z_]
    фишка интересная, можно что нибудь покрашить обойдя фильтры
    но собственно вопрос это нормальное поведение регулярок? и если да то в чем подвох?

    p.s. сори если не в той теме пишу
     
    _________________________
  17. t0ma5

    t0ma5 Reservists Of Antichat

    Joined:
    10 Feb 2012
    Messages:
    829
    Likes Received:
    815
    Reputations:
    90
    хм, похоже замешан символ конца строки $, срабатывает только на один \n и только в конце строки

    Code:
    123@123:~$ cat 1.pl 
    $a = "qwerwe\n";
    $b = "123123\n";
    if($a=~/^([0-9a-z]*)$/s) { print "1 yes\n" }
    print "match: '$1'\n";
    if($a=~/^([0-9a-z]+)$/s) { print "2 yes\n" }
    print "match: '$1'\n";
    if($a=~/^([\w]+)$/s) { print "3 yes\n" }
    print "match: '$1'\n";
    if($a=~/^([\w]*)$/s) { print "4 yes\n" }
    print "match: '$1'\n";
    if($b=~/^([\d]+)$/s) { print "5 yes\n" }
    print "match: '$1'\n";
    if($b=~/^([\d]*)$/s) { print "6 yes\n" }
    print "match: '$1'\n";
    if($a=~/^([0-9a-z]{1,})$/s) { print "7 yes\n" }
    print "match: '$1'\n";
    if($a=~/^([\w]{1,})$/s) { print "8 yes\n" }
    print "match: '$1'\n";
    if($b=~/^([\d]{1,})$/s) { print "9 yes\n" }
    print "match: '$1'\n";
    if($a=~/^([a-z]+)$/s) { print "10 yes\n" }
    print "match: '$1'\n";
    if($a=~/^(qwerwe)$/s) { print "11 yes\n" }
    print "match: '$1'\n";
    
    123@123:~$ perl 1.pl 
    1 yes
    match: 'qwerwe'
    2 yes
    match: 'qwerwe'
    3 yes
    match: 'qwerwe'
    4 yes
    match: 'qwerwe'
    5 yes
    match: '123123'
    6 yes
    match: '123123'
    7 yes
    match: 'qwerwe'
    8 yes
    match: 'qwerwe'
    9 yes
    match: '123123'
    10 yes
    match: 'qwerwe'
    11 yes
    match: 'qwerwe'
    
     
    _________________________
  18. Kaimi

    Kaimi Well-Known Member

    Joined:
    23 Aug 2007
    Messages:
    1,732
    Likes Received:
    811
    Reputations:
    231
    Так в чем вопрос то? В документации написано:

    ^ Match the beginning of the line
    $ Match the end of the string (or before newline at the end of the string)
     
    _________________________
  19. t0ma5

    t0ma5 Reservists Of Antichat

    Joined:
    10 Feb 2012
    Messages:
    829
    Likes Received:
    815
    Reputations:
    90
    проблема в чтении доков -_- извиняюсь
     
    _________________________
  20. AlexG

    AlexG Member

    Joined:
    26 Sep 2015
    Messages:
    57
    Likes Received:
    12
    Reputations:
    5
    Никогда толком не сталкивался регулярками, но тут пришлось. Помогите с такой регуляркой. Делаю разбор xml вот так:
    Code:
    $a = preg_replace ("/<teg1>(.*)<\/teg1>/","<b>$1</b>",$file);
    $b = preg_replace ("/<teg121>\s*\S*\s*<teg2>(.*)<\/teg2>/","<b>$1</b>",$file);// теги повторяются некоторые, пробую фильтровать по предидущему
    ...
    $n = preg_replace ("/<tegN>(.*)<\/tegN>/","<b>$1</b>",$file);
    
    При проверке типа echo $a;echo $b;... echo $n
    получается какая-то фигня - кроме самого кармана в переменные попадает еще и оставшееся содержимое файла.
    Вопрос - как в php переменную положить только содержимое кармана?
    UPD Кажется понял откуда мусор - если нет соответствия заданному шаблону, то туда запихивается все те соответствия которые существуют. Как от этого избавиться? Или как правильно проверить на сущестование? (например $b из примера выше)
     
    #20 AlexG, 21 Dec 2015
    Last edited: 24 Dec 2015