регулярное выражение php отделяет точное слово от строки в разных группах - PullRequest
5 голосов
/ 18 октября 2019

Я перепробовал все, что знаю, но все еще не могу понять, как решить эту проблему:

У меня есть строка, например:

  • "--included-- in selling price: 5 % vat usd 10.00 packaging fees 2 % notifying fees"
  • "--not included-- in selling price: us$ 35.00 express fees 2 % notifying fees"

Я хочу знать, являются ли налоги "включенными" или "исключенными", и если сборы "%" или "валюта", проблема в том, что они не обнаруживаютвалюта "usd", пока она привязана к названию таксона "vat usd"

как я могу отделить валюту от названия таксона в разных группах.

вот что ясделал

(--excluded--|--included--|--not included--)([a-z ]*)?:?(usd | aed | mad | € | us\$ )?([ \. 0-9 ]*)(%)?([a-z A-z ?]*) (aed|mad|€|us\$)*((aed|mad|€|us\$)+)?([\. 0-9 ]*)(%)?([a-z A-z]*)(.*)?

и вот что я получил

Match 1
Full match  0-83    --included-- in selling price: 5 % vat usd 10.00 packaging fees 2 % notifying fees

Group 1.    0-12    --included--

Group 2.    12-29    in selling price

Group 4.    30-33    5 

Group 5.    33-34   %

Group 6.    34-42    vat usd

Group 10.   43-49   10.00 

Group 12.   49-64   packaging fees 

Group 13.   64-82   2 % notifying fees

и вот что я хочу

Match 1
Full match  0-83    --included-- in selling price: 5 % vat usd 10.00 packaging fees 2 % notifying fees

Group 1.    0-12    --included--

Group 2.    12-29    in selling price

Group 4.    30-33    5 

Group 5.    33-34   %

Group 6.    34-38    vat

Group 7.    38-42    usd

Group 10.   43-49   10.00 

Group 12.   49-64   packaging fees 

Group 13.   64-82   2 % notifying fees

1 Ответ

2 голосов
/ 18 октября 2019

Вот решение:

$s = "--included-- in product price: breakfast --excluded--: 5 % vat aed 10.00 destination fee per night 2 % municipality fee 3.5 % packaging fee 10 % warranty service charge";
$results = [];
if (preg_match_all('~(--(?:(?:not )?in|ex)cluded--)(?:\s+([a-zA-Z ]+))?:+\s*((?:(?!--(?:(?:not )?in|ex)cluded--).)*)~su', $s, $m, PREG_SET_ORDER, 0)) {
    foreach ($m as $v) {
        $lastline=array_pop($v); // Remove last item //print_r($details);
        if (preg_match_all('~(?:(\b(?:usd|aed|mad|usd)\b|\B€|\bus\$)\s*)?\d+(?:\.\d+)?(?:(?!(?1))\D)*~ui', $lastline, $details)) {
            $results[] = array_merge($v, $details[0]);
        } else {
            $results[] = $v;
        }
    }
}
print_r($results);

См. PHP демо .

Примечания :

Первыйрегулярное выражение извлекает каждый матч, который вам нужно проанализировать. См. первая демонстрационная версия регулярного выражения . Это означает:

  • (--(?:(?:not )?in|ex)cluded--) - Группа 1: более короткая версия (--excluded--|--included--|--not included--): --excluded--, --included-- или --not included--
  • (?:\s+([a-zA-Z ]+))? - опциональнопоследовательность: 1+ пробелов, а затем группа 2: 1+ букв или пробелов ASCII
  • :+ - 1 или более двоеточий
  • \s* - 0+ пробелов
  • ((?:(?!--(?:(?:not )?in|ex)cluded--).)*) - Группа 3: любой символ, 0+ вхождений, как можно больше, не начинающий ни одну из трех последовательностей символов: --excluded--, --included--, --not included--

ЗатемЗначение группы 3 необходимо дополнительно проанализировать, чтобы собрать все детали. Второе регулярное выражение используется здесь для соответствия

  • (?:(\b(?:usd|aed|mad|usd)\b|\B€|\bus\$)\s*)? - необязательное вхождение
    • (\b(?:usd|aed|mad|usd)\b|\B€|\bus\$) - Группа 1:
      • \b(?:usd|aed|mad|usd)\b - usd, aed, mad или usd как целые слова
      • \B€ - без предшествующего слова char
      • \bus\$- us$ без предшествующего слова char
    • \s* - 0+ пробелов
  • \d+
  • (?:\.\d+)? - необязательная последовательность . и 1+ цифр
  • (?:(?!(?1))\D)* - любой нецифровый символ, 0 или более вхождений, как можно больше, не начинающих тот же шаблон, что и в группе 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...