【问题标题】:PHP - regular expression to remove domain name from rowPHP - 从行中删除域名的正则表达式
【发布时间】:2019-03-05 07:22:33
【问题描述】:

我正在从数据库中获取很多产品行。

其中一些行包含一个域名(例如 google.com),我希望在输出之前将其从字符串中删除(修剪)。 注意:有多个 TLD(.se、.fi.、.net、.org ...)

首先,我将从域表中获取所有域名到自己的数组中,然后使用preg_match(),运行测试字符串是否包含特定域。如果没有从产品行中找到域,则无需修剪任何内容。

domains 数组如下所示:

[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'] 中修剪域名。

【问题讨论】:

  • 那么,有什么问题?
  • 上面的正则表达式不会从$row['product']中删除域名,它会返回原来的。

标签: php regex


【解决方案1】:

这是一种方法,只需将 $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;
}

【讨论】:

  • 但有一件事......我仍然没有看到你在哪里设置或增加数组 $table[$i] 中的变量 ($i) ....
  • 不小心从源代码中省略了。这似乎可以解决问题,我会接受这个作为答案。干杯! :)
【解决方案2】:

总结

这是一个美丽的。你会喜欢这个答案的。

} 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

【讨论】:

  • 但是当没有匹配时,这并不能阻止多个 }else{ 块运行,域循环中的 }else{ 需要移出域循环和 if() 问题如果 $trimmed 仍然为空,则在该循环之后添加,即;未找到匹配项...
  • 是的,我可能也会重组循环,但continue 2; 是侵入性最小的解决方案。
猜你喜欢
  • 1970-01-01
  • 2010-10-20
  • 1970-01-01
  • 2013-06-21
  • 2019-08-20
  • 1970-01-01
  • 2011-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多