【问题标题】:php remove duplicates from string, if duplicate length is > 4php从字符串中删除重复项,如果重复长度> 4
【发布时间】:2019-05-12 23:32:37
【问题描述】:

我想删除重复项,如果这些重复项的长度超过 4 个字符。

我们怎样才能做到这一点?我当前的代码也删除了重复的 - 值。

代码:

$seoproducttitle = 'HP Chromebook Chromebook 11 G5 EE - 11.6 inch - Intel® Celeron® - 4LT18EA#ABH';
$productnamestring = $seoproducttitle;
$findseo = array('/\h+inch (?:(i[357])-\w+|\h+\w+)?/', '/(\w+)#\w+/');
$replaceseo = array('" $1', '$1');
$productnamingseo = preg_replace($findseo, $replaceseo, $productnamestring);
echo implode(' ', array_unique(explode(' ', $productnamingseo)));

这输出:HP Chromebook 11 G5 EE - 11.6" Intel® Celeron® 4LT18EA

它应该输出:HP Chromebook 11 G5 EE - 11.6" - Intel® Celeron® - 4LT18EA

或者:Apple MacBook Air MacBook Air - 13.3 英寸 - Intel Core i5-8e - MRE82N/A

应该是:Apple MacBook Air - 13.3 英寸 - Intel Core i5-8e - MRE82N/A

示例:http://sandbox.onlinephpfunctions.com/code/5bcaaf47ca97d6dee359802f2d71c2d889c0d091

【问题讨论】:

  • 这有点令人困惑。复制什么?您能否提供一些示例输入/预期输出?
  • @FrankerZ 在这种情况下,字符串的值是“Chromebook”的两倍。当重复的长度超过 4 个字符时,我想删除所有重复的值。所以在上面的字符串中它应该只删除 1 'Chromebook'。但它不应该删除重复的“-”符号。
  • 请使用这些示例/说明编辑您的原始问题。
  • @FrankerZ 我编辑了问题,另见示例。

标签: php regex duplicates


【解决方案1】:

更新

基于 OP 的 cmets,所需的正则表达式是

/(^| )(.{4,}) (.*)\2/

这会查找一组 4 个或更多字符,前面有一个空格或行首,后面有一个空格,一些其他字符,然后该组再次重复。正则表达式被替换为$1$2 $3,它有效地删除了重复的字符串。举几个例子:

$seoproducttitle = 'Apple MacBook Air MacBook Air - 13.3 inch - Intel Core i5-8e - MRE82N/A';
echo preg_replace('/(^| )(.{4,}) (.*)\2/', "$1$2 $3", $seoproducttitle) . "\n";
$seoproducttitle = 'HP Chromebook 11 G5 EE Chromebook - 11.6 inch - Intel® Intel® Celeron® - 4LT18EA#ABH 4LT18EA#ABH';
echo preg_replace('/(^| )(.{4,}) (.*)\2/', "$1$2 $3", $seoproducttitle) . "\n";

输出:

Apple MacBook Air - 13.3 inch - Intel Core i5-8e - MRE82N/A Array
HP Chromebook 11 G5 EE - 11.6 inch - Intel® Celeron® - 4LT18EA#ABH 

更新demo on 3v4l.org

原答案

你可以使用这个正则表达式:

\b([^ ]{4,})( |$)(.*)\1

它查找一组 4 个或更多非空白字符,后跟一个空格或字符串结尾,然后是一些其他字符,然后第一组重复。正则表达式替换为$1$3,它有效地删除了重复的字符串。例如

$seoproducttitle = 'HP Chromebook 11 G5 EE Chromebook - 11.6 inch - Intel® Intel® Celeron® - 4LT18EA#ABH 4LT18EA#ABH';
echo preg_replace('/\b([^ ]{4,})( |$)(.*)\1/', "$1$3", $seoproducttitle);

输出:

HP Chromebook11 G5 EE - 11.6 inch - Intel® Celeron® - 4LT18EA#ABH

Demo on 3v4l.org

【讨论】:

  • 谢谢尼克!但我也需要保留我当前的代码,以便它继续替换其他东西。所以我需要扩展我当前的代码。如何做到这一点?
  • @HenkZ 只需将我的搜索和替换字符串添加到您的 $findseo$replaceseo 数组中,例如$findseo = array('/\h+inch (?:(i[357])-\w+|\h+\w+)?/', '/(\w+)#\w+/', '/\b([^ ]{4,})( |$)(.*)\1/'); $replaceseo = array('" $1', '$1', '$1$3');
  • 非常感谢!工作几乎完美,但我们也有这个标题:Apple MacBook Air MacBook Air - 13.3 英寸 - 英特尔酷睿 i5-8e - MRE82N/A。在这种情况下,它应该删除“MacBook Air”的第二部分。如何做到这一点?
  • @HenkZ 重复的是否总是相邻?
  • 是的,它们确实是相邻的。
【解决方案2】:

计算机只做我们告诉他们的事情,所以您首先需要用通俗易懂的语言向自己解释这个过程。然后将 that 翻译成代码。然后,如果您在执行此操作时遇到问题 ,您至少可以在 StackOverflow 上发布问题的正确描述。

$words = explode(' ', $productnamingseo);
// start with an empty list of words we've seen
$output = [];
// for every word
foreach($words as $word) {
    // if it's longer than 4 chars and we've already seen it
    if( mb_strlen($word) >= 4 && in_array($word, $output) ) {
        // debug: show omitted words
        // $output[] = str_repeat('X', mb_strlen($word));
        // skip it
        continue;
    }
    // otherwise, add it to the list of words we've already seen
    $output[] = $word;
}

var_dump(
    $productnamingseo,
    implode(' ', $output)
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-03
    • 2011-02-06
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多