1

仅匹配字符串: ,.:-如何从字符串中删除重复值?例如具有:

"ab::::c ---------d,,,e ..........f ::a-b,,,c..d"

预期输出:

"ab:c -d,e .f :a-b,c.d" 
4

3 回答 3

2

在这里,我们preg_replace用于实现所需的输出。

正则表达式: ([,.:-])\1+ 正则表达式演示

或者

正则表达式: (,|\.|:|-)\1+正则表达式演示

1.这将匹配一个字符并将其添加到捕获的组中

2.使用该捕获的组\1不止一次发生。

替代品: $1

在此处尝试此代码段

<?php
ini_set('display_errors', 1);

$string="ab::::c ---------d,,,e ..........f ::a-b,,,c..d";
echo preg_replace('/([,.:-])\1+/', '$1', $string);

解决方案2: using foreach loop

在此处尝试此代码段

$string="aab::::css ---------ddd,,,esddsff ..........f ::a-b,,,c..d";
$chars=  str_split($string);
$result=array();
foreach($chars as $character)
{
    if($character!=end($result) ||  !in_array($character, array(":",",",".","-")))
    {
        $result[]=$character;
    }
}
print_r(implode("",$result));
于 2017-05-29T15:53:47.030 回答
1

对于未来的读者,为了获得最大效率,请不要在模式中使用管道字符。使用循环的方法也进行了太多的迭代函数调用和/或条件。

输入:$in="ab::::c ---------d,,,e ..........f ::a-b,,,c..d";

方法#1:单行使用preg_replace()(注意空替换字符串)

echo preg_replace('/([,.:-])\K\1+/','',$in);
//                          ^^ resets the start of the matched substring

preg_split()方法 #2:使用&的单行implode()

echo implode(preg_split('/([,.:-])\K\1+/',$in));  // empty glue doesn't need mentioning

使用任一方法输出:

ab:c -d,e .f :a-b,c.d

我想知道在这个页面上哪种方法最有效。如果有人愿意使用 Sahil 的 2 种方法和我的两种方法运行并发布基准测试,那将非常有启发性。


这是一个较晚的考虑...如果您的字符串在移动到有效字符之前仅存在符号重复自身的问题,那么您可以使用此模式:[-.,:]\K[-.,:]+ 它的执行速度比此页面上的所有其他模式快 50%,并且它提供与此页面上的其他方法相同的输出,但确实延伸了您对问题的解释。以下是一些揭示差异的示例:

ab:-,.c; 将减少到ab:c
ab:-,.c -d.,.e--f将减少到ab:c -d.e-f

这可能适合也可能不适合您的项目。

于 2017-05-31T01:56:37.180 回答
0

您可以使用preg_replace执行此操作:

preg_replace — 执​​行正则表达式搜索和替换

$pattern = '/(\.|\,|\:|\-){2,}/';
$string = 'ab::::c ---------d,,,e ..........f ::a-b,,,c..d';
echo preg_replace($pattern, '$1', $string);

您可以在这里尝试您的正则表达式:https ://regex101.com/

于 2017-05-29T16:05:09.620 回答