PHP - регулярное выражение для удаления доменного имени из строки - PullRequest
0 голосов
/ 05 марта 2019

Я выбираю много строк продукта из базы данных.

Некоторые из этих строк содержат доменное имя (например, google.com), которое я хотел бы удалить (обрезать) изстрока перед выводом. ПРИМЕЧАНИЕ. Существует несколько доменов верхнего уровня (.se, .fi., .Net, .org ...)

Сначала я извлеку все доменные имена из таблицы доменов в собственный массива затем с preg_match() запустите проверку, содержит ли строка определенный домен или нет.Если домен не найден в строке продукта, ничего не нужно обрезать.

Вот как будет выглядеть массив доменов:

[0] => Array
        (
            [domain] => google.com
        )
 [1] => Array
        (
            [domain] => google.se
        )

Вот пример строк, выведенных из базы данных:

Product 1 - Test purposes 1
Product 2 - Test purposes 2 google.com
Product 2 - Test purposes 2 google.se

И вот что я попробовал до сих пор:

<?php
...
$table = [];

# loop through all rows from the database
while ($row = $stmt->fetch()) {
    # loop through all domains
    foreach($domains as $domain) {
        if(preg_match("/{$domain['domain']}/i", $row['product'],$matches, PREG_OFFSET_CAPTURE)) {
            $trimmed = str_replace($domain['domain'], '', $row['product']) ;
            $table[$i]['product'] = $trimmed;
        } else {
            $table[$i]['product'] = $row['product'];
        }
    }
}

Это игнорирует все найденные домены и просто использует исходный $row['product'] вместо обрезки доменного имени.от $row['product'].

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Вот один из способов сделать это, просто установите переменную $ multi на то, что вы используете ....

// (?) could have more than one domain match true / false

$multi = FALSE;

while ( $row = $stmt->fetch ( ) )
{
    // loop through all domains

    $trimmed = $row['product'];

    foreach ( $domains as $domain )
    {
        if( preg_match ( "/{$domain['domain']}/i", $trimmed ) )
        {
            $trimmed = str_replace ( $domain['domain'], '', $trimmed );

            if ( $multi === FALSE )
            {
                break;
            }
        }
    }

    $table[$i]['product'] = $trimmed;
}
0 голосов
/ 05 марта 2019

Резюме

Это красивый.Вам понравится ответ.

Добавьте следующую строку перед } else {:

continue 2;

Объяснение

Поскольку вы выполняете двойной цикл, если соответствующий домен не является последним, он переопределит домен, который сделал совпадение.Таким образом, вам нужно сразу перейти к следующей строке , а не только к следующему домену , как только вы найдете совпадение.

Код

<?php

$domains = [
    ["domain" => "google.com"],
    ["domain" => "google.se"]
];

$rows = [
    ["product" => "Product 1 - Test purposes 1"],
    ["product" => "Product 2 - Test purposes 2 google.com"],
    ["product" => "Product 2 - Test purposes 2 google.se"],
];

$table = [];

# loop through all rows from the database
foreach($rows as $id => $row){
    # loop through all domains
    foreach($domains as $domain) {
        if(preg_match("/{$domain['domain']}/i", $row['product'],$matches, PREG_OFFSET_CAPTURE)) {
            $trimmed = str_replace($domain['domain'], '', $row['product']) ;
            $table[$id]['product'] = $trimmed;
            continue 2;
            //As soon as you hit a match, go to the next *row*.
            //Don't try to match any more domains.
        } else {
            $table[$id]['product'] = $row['product'];
        }
    }
}

var_dump($table);

Предостережения

Предполагается, что у вас есть только одно совпадение домена на строку.

https://3v4l.org/Oo2Ie

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...