2012-03-10 51 views
1

我有一些串这样的:替换内 “空间”,preg_replace函数PHP

I:11;:5:{S:2: “ID”; S:4: “1097”; S :5:“iName”; s:12:“Ovo de Andre”; s:10:“dropChance”; s:4:“2000”; s:4:“type”; i:1; s:5:“kName”; s:12:“安德烈Ovo”;

而且,我想知道我怎么能替换字符串:“大毛德安德烈”到这样的事情:

“Ovo_de_Andre”,但不能更改任何空间,可能会出来“”。

我尝试:

$字符串= preg_replace函数( '/ “?。?()\ S()”/米', ' “$ 1_ $ 2”',$串);

,但它只是代替了第一空间,则该字符串看起来像这样:

I:11;:5:{S:2: “ID”; S:4:” 1097“; s:5:”iName“; s:12:”Ovo_de Andre“; s:10:”dropChance“; s:4:”2000“; s:4:”type“; i:1; s:5:“kName”; s:12:“Ovo_de Andre”;

我知道我可以用一段时间来检查它,但它会对性能造成问题,我认为它会是多余的。

此外,我想知道如何做出同样的结果,而不是替换“”中的空格,将其替换掉,而不更改“”中的空格。

在此先感谢。


我有这个环节,使类似的东西,但我不能管理有什么改变,使其达到我想要什么: Using preg_replace to replace all occurrences in php

这里是完整的数据,我把它分成字符串,一个接一个地寻找错误。

$ string ='a:16:{'; $ string。='i:0; a:5:{s:2:“id”; s:4:“1113”; s:5:“iName”; s:5:“Drops”; s:10 : “dropChance”; S:4: “7500”; S:4: “类型”; I:1; S:5: “kName”; S:5: “滴”;}';$ string。='i:1; a:5:{s:2:“id”; s:4:“1585”; s:5:“iName”; s:11:“Mime Monkey”; s: 10:“dropChance”; s:4:“7000”; s:4:“type”; i:1; s:5:“kName”; s:11:“Mime Monkey”;}'; $ string。='i:2; a:5:{s:2:“id”; s:4:“1027”; s:5:“iName”; s:7:“Raptice”; s:10 : “dropChance”; S:4: “7000”; S:4: “类型”; I:1; S:5: “kName”; S:7: “Raptice”;}'; $ string。='i:3; a:5:{s:2:“id”; s:4:“1002”; s:5:“iName”; s:6:“Poring”; s:10 : “dropChance”; S:4: “7000”; S:4: “类型”; I:1; S:5: “kName”; S:6: “波令”;}'; $ string。='i:4; a:5:{s:2:“id”; s:4:“1767”; s:5:“iName”; s:8:“Deviling”; s:10 : “dropChance”; S:4: “5000”; S:4: “类型”; I:2; S:5: “kName”; S:8: “Deviling”;}'; $ string。='i:5; a:5:{s:2:“id”; s:4:“1767”; s:5:“iName”; s:8:“Deviling”; s:10 : “dropChance”; S:4: “5000”; S:4: “类型”; I:2; S:5: “kName”; S:8: “Deviling”;}'; $ string。='i:6; a:5:{s:2:“id”; s:4:“1766”; s:5:“iName”; s:8:“Angeling”; s:10:“dropChance” ; S:4: “5000”; S:4: “类型”; I:2; S:5: “kName”; S:8: “Angeling”;}'; $ string。='i:7; a:5:{s:2:“id”; s:4:“1766”; s:5:“iName”; s:8:“Angeling”; s:10 : “dropChance”; S:4: “5000”; S:4: “类型”; I:2; S:5: “kName”; S:8: “Angeling”;}'; $ string。='i:8; a:5:{s:2:“id”; s:4:“1004”; s:5:“iName”; s:6:“Zangão”; s:10 : “dropChance”; S:4: “3500”; S:4: “类型”; I:1; S:5: “kName”; S:6: “Zangão”;}'; $ string。='i:9; a:5:{s:2:“id”; s:4:“1236”; s:5:“iName”; s:12:“Ovo de Andre”; s :10:“dropChance”; s:4:“3000”; s:4:“type”; i:1; s:5:“kName”; s:12:“Ovo de Andre”;}'; $ string。='i:10; a:5:{s:2:“id”; s:4:“1076”; s:5:“iName”; s:9:“Esqueleto”; s:10 : “dropChance”; S:4: “3000”; S:4: “类型”; I:1; S:5: “kName”; S:9: “Esqueleto”;}'; $ string。='i:11; a:5:{s:2:“id”; s:4:“1097”; s:5:“iName”; s:12:“Ovo de Andre”; s :10:“dropChance”; s:4:“2000”; s:4:“type”; i:1; s:5:“kName”; s:12:“Ovo de Andre”;}'; $ string。='i:12; a:5:{s:2:“id”; s:4:“1051”; s:5:“iName”; s:14:“Besouro-Ladrão”; s :10: “dropChance”; S:4: “2000”; S:4: “类型”; I:1; S:5: “kName”; S:14: “Besouro-Ladrão”;}'; $ string。='i:13; a:5:{s:2:“id”; s:4:“1183”; s:5:“iName”; s:16:“ChonChon Raivoso”; s: 10:“dropChance”; s:4:“1500”; s:4:“type”; i:1; s:5:“kName”; s:16:“ChonChon Raivoso”;}';
$ string。='i:14; a:5:{s:2:“id”; s:4:“1011”; s:5:“iName”; s:8:“ChonChon”; s: 10: “dropChance”; S:4: “1500”; S:4: “类型”; I:1; S:5: “kName”; S:8: “飞头”;}'; $ string。='i:15; a:5:{s:2:“id”; s:4:“1784”; s:5:“iName”; s:5:“Stapo”; s:10 : “dropChance”; S:4: “1000”; S:4: “类型”; I:1; S:5: “kName”; S:5: “Stapo”;}'; $ string。='}';

如果仔细打量,你会在通知行我:0和我:矢量11显示了行号和数据的大小存在数据之间存在一些空间。

+2

这看起来像一个序列化的阵列,你为什么不先反序列化?无论如何,如果你只是想替换空格,那么就不需要正则表达式。看看['str_replace'](http://php.net/manual/en/function.str-replace.php)。 – 2012-03-11 17:48:41

+0

str_replace将替换“”之外的空格,因此它会破坏这个字符串,因为它不是一个完美的序列化的字符串,我要求的这个函数会删除超出真正的序列化字符串的空格,使其成为正确的序列化字符串。 – Marcelo 2012-03-11 17:52:45

+0

好吧@Marcelo - 我在这里看到你已经阐明了你没有一个有效的序列化对象。那么不理我的答案! – calumbrodie 2012-03-11 18:01:19

回答

2

这应该工作:

$str = <<< EOF 
i: 11;a:5: {s:2:"id";s:4:"1097";s:5:"iName";s:12:"Ovo de Andre";s:10:"dropChance";s:4:"2000";s:4:"type"; i:1;s:5: "kName"; s:12: "Ovo de Andre" 
EOF; 
$str = preg_replace_callback('#("[^"]*")#', 
     create_function('$m', 
      'return str_replace(" ", "_", $m[1]);'), 
     $str); 
echo $str . "\n"; 

更新:由于OP喜欢有这种置换只有单一的正则表达式,这里是一个使用负前瞻:

$str = preg_replace('#\s(?!([^\"]*\"[^\"]*\")*[^\"]*$)#', '_', $str); 
echo $str . "\n"; 

总之这正则表达式找到一个空间,它是不是后跟偶数个双引号,这意味着发现空间在双引号henc它被分数低下所取代。

OUTPUT:

i: 11;a:5: {s:2:"id";s:4:"1097";s:5:"iName";s:12:"Ovo_de_Andre";s:10:"dropChance";s:4:"2000";s:4:"type"; i:1;s:5: "kName"; s:12: "Ovo_de_Andre" 
+1

create_function? wtf – dynamic 2012-03-11 17:56:33

+0

它像一个魅力工作,谢谢,但我希望它可能是一种方式,我不需要回调来做到这一点。 就像在这篇文章中:http://stackoverflow.com/questions/4643442/using-preg-replace-to-replace-all-occurrences-in-php – Marcelo 2012-03-11 18:40:00

+0

如果我有15个声望点,我会为你投票。 – Marcelo 2012-03-11 18:55:11

1

编辑:OP澄清该字符串不是有效的序列化对象...

我不知道你是否会被操纵这个对象更进一步,或者它来自哪里,但是如果是我,我会做的第一件事是反序列化它(这是假设你有一个序列化对象:它看起来像它,尽管你发布的确切字符串不是一个有效的序列化对象,我正在做假设t帽子你没有发布整个字符串)。

http://www.php.net/manual/en/function.unserialize.php

一旦你有你在,你就可以开始每个属性的基础上应用的变换的可感知的格式阵列...

//unserialize 
$person = unserialize($yourstring); 

// now perfrom transformations 
$person['iName'] = str_replace(' ', '_', $person['iName']); 
$person['kName'] = str_replace(' ', '_', $person['kName']); 
// etc... 

// now re-serialize 
$person = serialize($person); 

上使用正则表达式的对象/数组的属性进行变换的群众只是一个噩梦 - 可以很容易对自己和使用PHP本机功能来帮助你!

如果你有一个序列化的对象,然后忽略这个答案。

+0

这不适合,因为它不是一个完美的序列化对象。 – Marcelo 2012-03-11 18:18:52

0

如果可能的话,我会避免使用正则表达式,因为您可以轻松地反序列化并读取值,然后将其序列化。这将确保你确切知道你在改变什么。

http://www.php.net/manual/en/function.unserialize.php

function space_to_underscore($str) { 
    return str_replace(' ', '_', $str); 
} 
+0

我无法反序列化,因为它在数据键之间有空格,用于指定有多少数据以及值的起始位置。 – Marcelo 2012-03-11 18:20:02