从字符串中删除值

4

如果我有一个带有ID的字符串

$myIDs = '22,34,445,67889,23';

如果我有一个字符串和一个值,如何从字符串中删除这个值,假设我确定它在字符串中存在?

$removeID = '445';

我应该使用preg_replace函数还是有更好的方法?例如,如果字符串中间只删除一个值,那么最终会出现两个逗号,然后需要将它们替换为一个逗号。

preg_replace($removeID, '', $myIDs);

更新:这些都是很好的建议。然而,我刚想到一个潜在问题。这可能需要处理成数组而不是正则表达式。如果我的字符串长下面这样

$myIDs = '2312,23,234234';

移除的 ID

$removeID = '23';

有太多的潜在匹配...



关于您的更新:下面几乎所有的答案都考虑了这种可能性。因此,是的,如下所示,使用正则表达式绝对可以实现这一点。 - poke
7个回答

3
$array = explode(',',$myIDs);
$array = array_diff($array,array($removeID));
$output = implode(',',$array);

1
这是一个数据列表,因此最简单的操作方式是使用数组! - fredley
1
这可能会因字符串的大小而变得低效。我不想看到这样的事情发生在一个有100K个ID的字符串上... - ircmaxell
同意,但对于@Santa的数据集来说没问题。此外,使用数组或正则表达式存在内存/CPU平衡的问题。 - fredley
@fredley:我很好奇,所以我写了一个简单的基准测试脚本。数组操作大约比我想出来的正则表达式慢两倍。肯定是微小优化,但这只说明它并不比正则表达式更有效率(正则表达式是CPU绑定的,而这个则是内存和CPU绑定的)。 - ircmaxell
@ircmaxell:你的测试ID字符串有多长? - poke
@poke:上面给出的字符串。我还测试了一个500个元素的,它需要正则表达式的3倍时间... - ircmaxell

3
您可以使用正则表达式:
$remove = preg_quote($removeID, '/');
$regex = '/,'.$remove.'$|^'.$remove.',|^'.$remove.'$|,'.$remove.'(?=,)/';
$myIDs = preg_replace($regex, '', $myIDs);

这句话的意思是:将$removeID替换成它前面是字符串开头或逗号,后面是字符串结尾或另一个逗号的位置。

编辑:我已经改变了正则表达式为一个经过测试的正则表达式(我测试了所有可能性,并且它似乎在我能想到的所有情况下都可以工作)...


但是如果去掉“2”,这不会将“1,2,3”变成“13”吗? - NikiC
但现在它会保留 ,,。 (这是预期的吗?)也许应该尝试 /,RM$|(?<=^|,)RM,/?虽然不太好看,但应该可以正确地删除逗号。 - NikiC
现在它不会删除第一个值,我的建议是:$regex='/ (^'.$remove。'|,'.$remove.'(?=,)|(,|^)'.$remove.'$)/'; - meze

2
这里是一个正则表达式,可以用来匹配 "89" 这个项目:
/(^|,)89(?=,|$)/

它匹配字符",89"(或者如果它在输入的开头,则只匹配"89"),只要它直接后面跟着另一个","或输入的结尾。

通过适当的转义和一些抽象化:

<?php
$myIDs = '23,45,678967,89,12';
$toRemove = 89;

$myIDs = preg_replace('/(^|,)' . preg_quote($toRemove) . '(?=,|$)/', '', $myIDs);
?>

已经测试多次输入。

希望这有所帮助!


实际上字符串可以采用以下格式:'89'或'1,89,3'或'1,89'或'89,3',即可以有逗号(前|后)也可以没有。 - santa
@ircmaxell:不是的。结尾处的捕获是一个前瞻断言。 - Lightness Races in Orbit
@ircmaxell: 请自行尝试:http://www.regular-expressions.info/javascriptexample.html - Lightness Races in Orbit

1
$myIDs = '1,2,3,4,5';
$remID = '5';

$myIDs = preg_replace(array("/^$remID,|(?:,|^)$remID$/","/,$remID,/"),
                      array('',','),
                      $myIDs);

Ideone链接


如果您有$myIDs = '1, 2, ,500';会发生什么?您最终得到的是1,2, ,00... - ircmaxell
@ircmaxell为什么这个字符串必须是'1, 2, ,500'?我想我们假设这个字符串正确地列出了用逗号分隔的数字。 - Donovan
这正是我想用模式和替换数组来实现的,但你比我更快。 - Wiseguy
从正则表达式的第一个选项中删除 ?。否则,5 将匹配 500,10,11 - ircmaxell

1
$myarray=explode(',', $myIDs)
$excluded=preg_grep('^' . $removeID . '$', $myarray, PREG_GREP_INVERT)
$newId=join(',', $excluded)

1
运行正则表达式来检查数组元素的相等性是非常低效的。使用 array_filter 函数和一个简单的回调函数来检查相等性会更好。 - poke

1

我也要提供一个解决方案:

preg_replace( '/\b(,' . $rID . '|' . $rID . ',|' . $rID . ')\b/', '', $myIDs );

preg_replace( '/\b(,445|445,|445)\b/', '', $myIDs );

(示例)


-1

最简单的方法是这样的:

$myIDs = '22,34,445,67889,23';
$removeID = 445;

$myIDs = preg_replace("/($removeID,|,$removeID)/", '', $myIDs);

更新:

$myIDs = preg_replace("/(^$removeID,|,$removeID$|,$removeID(?=,))/", '', $myIDs);

例如,当$removeID的值为889时,无法正常工作。 - ircmaxell
我喜欢简洁,但如果字符串只有一个ID,那么没有逗号怎么办? - santa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接