Php 如何用正则表达式模式替换正则表达式模式?
我觉得很傻,因为我没能弄明白这一点,但我就是弄不明白。我需要用模式替换正则表达式字符串,我发现了两个这样做的示例,但它们确实让我比以往任何时候都更加困惑 这是我目前的尝试:Php 如何用正则表达式模式替换正则表达式模式?,php,regex,csv,match,Php,Regex,Csv,Match,我觉得很傻,因为我没能弄明白这一点,但我就是弄不明白。我需要用模式替换正则表达式字符串,我发现了两个这样做的示例,但它们确实让我比以往任何时候都更加困惑 这是我目前的尝试: $string = '26 14:46:54",,"2011-08-26 14:47:02",8,0,"BUSY","DOCUMENTATION","1314370014.18","","","61399130249","7466455647","from-internal","""Oh Snap"" <6139913
$string = '26 14:46:54",,"2011-08-26 14:47:02",8,0,"BUSY","DOCUMENTATION","1314370014.18","","","61399130249","7466455647","from-internal","""Oh Snap"" <61399130249>","SIP/1037-00000014","SIP/CL-00000015","Dial","SIP/CL/61436523277,45","2011-08-26 14:47:06","2011-08-26 14:47:15","2011-08-26 ';
$pattern = '["SIP/CL/\d*?,\d*?",]';
$replacement = '"SIP/CL/\1|\2",';
$string = preg_replace($pattern, $replacement, $string);
print($string);
格式不好的CSV中的逗号会使我的其他一些脚本相形见绌。如果缺少大括号,则模式应如下所示:
$pattern = '["SIP/CL/(\d*),(\d*)",]';
我想你需要这个:
$pattern = '["SIP/CL/(\d+),(\d+)",]';
parens-()
-捕获内部匹配,允许您在替换模式中引用它
您还可以通过扩展匹配模式中的捕获来简化替换模式:
$pattern = '[("SIP/CL/\d+),(\d+",)]';
$replacement = '\1|\2';
$replacement
中的反向引用\1
和\2
是指$pattern
中捕获的组。捕获的组通过在其周围放置括号来保存()
尝试(我将您的正则表达式分隔符[]
更改为!
,等待下面评论的答复):
还要注意,由于$pattern
上有一个尾随逗号,如果$string
以结尾的“SIP/CL/61436523277,45”
将不会被转换。我建议删除后面的逗号
此外,您当前的正则表达式将“SIP/CL/,”
转换为“SIP/CL/|”
。如果这不是您的意图,请将*
后面的\d
(即0个或多个匹配项)更改为+
(一个或多个匹配项)。我这样做了
$string = '26 14:46:54",,"2011-08-26 14:47:02",8,0,"BUSY","DOCUMENTATION","1314370014.18","","","61399130249","7466455647","from-internal","""Oh Snap"" <61399130249>","SIP/1037-00000014","SIP/CL-00000015","Dial","SIP/CL/61436523277,45","2011-08-26 14:47:06","2011-08-26 14:47:15","2011-08-26 ';
$pattern = '/SIP\/CL\/([0-9]+),([0-9]+)/';
$replacement = 'SIP/CL/\1|\2';
$string = preg_replace($pattern, $replacement, $string);
print($string);
$string='26 14:46:54“,“2011-08-26 14:47:02”,8,0,“忙”,“文档”,“1314370014.18”,“61399130249”,“7466455647”,“来自内部”,“Oh Snap”,“SIP/1037-00000014”,“SIP/CL-00000015”,“拨号”,“SIP/CL/61436523277,45”,“2011-08-26 14:47:06”,“2011-08-26 14:47:15”,“2011-08-26”;
$pattern='/SIP\/CL\/([0-9]+),([0-9]+)/';
$replacement='SIP/CL/\1 |\2';
$string=preg_replace($pattern,$replacement,$string);
打印($string);
它的格式似乎并不差,因为它位于引号之间。。。你用这个,不是吗?或者如果它是一根绳子,我不是,但我现在是。无论如何,我需要学习这种形式的正则表达式替换。于是一石二鸟:)。我知道fgetcsv,但它不适合我的用途(它是一个1.8GB+csv…,无法在mem中加载所有内容),但是str_getcsv工作得很好!)好的,供将来参考:fgetcsv
也不会将整个文件读取到内存中,只是逐行读取;)就这样?我觉得自己像个傻瓜。非常感谢:)这很好地工作了。您将非gready运算符置于括号外,从而改变了它的含义。应该是(\d+?)@user1130968标记最有用的答案,因为答案是表达感谢的最佳方式。)(FAQ也这么说)@meou你是对的,我没有注意到我只是添加了大括号,我根本不会使用它,最后看起来像$pattern='[“SIP/CL/(\d*),(\d*),]$替换=“‘SIP/CL/\1 |\2’”;在本例中,[和]将被视为delimeters,而不是字符类。模式1不会是SIP/CL/{numbershere},因此,如果您想要'“SIP/CL/(\d*?),(\d*?),'
,或者您的第一个引用很有趣。因为你的替代者是SIP/CL/SIP/CL/numbershere | numbersagain
@meouw,我忘了,干杯。但是它不应该是[
和[
或]
和]
而不是[
和]
吗?PHP和Perl一样,正确地将成对的括号识别为分隔符,所以[]
、
、{}
和
都可以工作。我认为在PHP中使用它们是个坏主意;与Perl不同的是,除了引号外,还必须使用正则表达式分隔符,这已经够令人困惑的了。至少,任何查看您的代码的人都会怀疑您是否理解它为什么有效
$pattern = '!"SIP/CL/(\d*?),(\d*?)",!';
$replacement = '"SIP/CL/\1|\2",';
$string = '26 14:46:54",,"2011-08-26 14:47:02",8,0,"BUSY","DOCUMENTATION","1314370014.18","","","61399130249","7466455647","from-internal","""Oh Snap"" <61399130249>","SIP/1037-00000014","SIP/CL-00000015","Dial","SIP/CL/61436523277,45","2011-08-26 14:47:06","2011-08-26 14:47:15","2011-08-26 ';
$pattern = '/SIP\/CL\/([0-9]+),([0-9]+)/';
$replacement = 'SIP/CL/\1|\2';
$string = preg_replace($pattern, $replacement, $string);
print($string);