Соответствие регулярному выражению справа налево

Я хотел сопоставить что-то справа налево, ниже один из таких примеров.

100abababab3x3x3xx1000morewords

Если я хочу сопоставить что-то между последним xx и непосредственно предыдущим ab и получить 3x3x3

Я пробовал что-то вроде ниже, но оно соответствует ababab3x3x3

preg_match('/ab(.*?)xx/',$text,$totmat);

Примечание: пожалуйста, не рекомендуйте strrev.

Приведенный выше пример предназначен только для иллюстрации, все, что я хотел сделать, это сопоставить справа налево.

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

Jan 09.11.2018 16:51

существует около 20 различных таблиц, и эта страница не соответствует никаким стандартам w3, поэтому, пожалуйста, ответьте на нее в общем виде регулярных выражений. как сопоставить 333 с точки зрения ababab333xx1000morewords

Gracie williams 09.11.2018 16:55

Неа. Дело в том, что xpath запросы в сочетании с регулярным выражением действительно эффективны, и вы действительно должны их использовать. Сами по себе регулярные выражения действительно ведут в тупик.

Jan 09.11.2018 16:58

Да, я понимаю, пожалуйста, посмотрите мою правку.

Gracie williams 09.11.2018 16:59

Регулярное выражение не самое лучшее для того, чего вы пытаетесь достичь - посмотрите в php DOMDocument - php.net/manual/en/class.domdocument.php

Stuart 09.11.2018 17:07

Проверить regex101.com/r/RmOOPh/1

Mohammad 09.11.2018 17:14

@Mohammad: примерно </td> <td align = "right"> 100 </td>

Gracie williams 09.11.2018 17:20

В вашем регулярном выражении вам нужно ограничить его определенным набором символов вместо точки, иначе он будет соответствовать чему угодно и может дать вам нежелательные результаты. Попробуйте с этим регулярным выражением <td align = "right"> ([\ d ,.] *) <\ / td> <td colspan = "4"> Но с этим способом вам нужно заранее знать, какие все символы могут появляться в ваш предполагаемый текст.

Pushpesh Kumar Rajwanshi 09.11.2018 17:24

@Graciewilliams Если ваш html будет </td> <td align = "right"> 100 </td>, как вы хотите получить от него 7 433,00?

Mohammad 09.11.2018 17:26

Похоже, что один - деньги, а другой - количество, можете ли вы положиться на эту информацию? /\d*?,?\d*?\.\d{2}/. Это ищет любое количество цифр, за которым следует необязательный ',', затем любое количество цифр, точка и 2 цифры.

Lou 09.11.2018 17:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
10
2 482
3

Ответы 3

Не уверены, что это наиболее оптимизированный способ? Но это сработает для вас, если вы используете комбинацию Смотри в будущее позитивно(?=) и Смотри за позитивом(?<=). См. регулярное выражение

<?php

$re = '/\w+(?<=ab)(.*?)(?=xx)/m';
$str = '100abababab3x3x3xx1000morewords';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

// Print the full matched result
echo $matches[0][1];

ДЕМО:https://3v4l.org/db69N

$str = '100abababab3x3x3xx1000morewords';
preg_match('/ab((?:(?!ab).)*)xx/', $str, $m);
print_r($m);

Выход:

Array
(
    [0] => ab3x3x3xx
    [1] => 3x3x3
)

> Объяснение:

ab              : literally ab
  (             : start group 1
    (?:         : start non capture group
      (?!ab)    : negative lookahead, make sure we doon't have ab
      .         : any character but newline
    )*          : end group, may appear 0 or more times
  )             : end group 1
xx              : literally xx

Существуют и другие подходы к этому типу проблемы, кроме регулярного выражения, которые были бы почти вдвое быстрее по времени вычислений.

Вот например:

$str = "100abababab3x3x3xx1000morewords";
$result = explode("ab", explode("xx", $str)[0]);
var_dump(end($result));

Первое появление разнесения разбивает строку на две части между символами «xx». Нас интересует только левая часть (индекс 0).

Второй случай разнесения разбивает нить с символами ab. Нас интересует только последнее появление ab. Поэтому var_dump(end($result)); печатает ожидаемый результат.

Другие вопросы по теме