Reputation: 188
I have some strings like this:
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";
And, I'd like to know how I could replace that string: "Ovo de Andre" to something like this:
"Ovo_de_Andre", but it can't change any spaces that could be out "".
I tried:
$string = preg_replace('/"(.?)\s(.?)"/m', '"$1_$2"', $string);
But it just replaces the first space, then the string looks like this:
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";
I know I could use a while to check it, but it'd be problematic to performance and I think it'd would be redundant.
Additionally, I want to know how could it be to make the same, but rather than replacing spaces within "", replace those out, without change spaces within "".
Thanks in advance.
I have this link that makes something similar but I couldn't manage what changing to make it reach what i want: Using preg_replace to replace all occurrences in php.
Here is the full data, I separeted it in strings to test one by one looking for errors that were there.
$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:"type";i:1;s:5:"kName";s:5:"Drops";}'; $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:"type";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:"type";i:1;s:5:"kName";s:6:"Poring";}'; $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:"type";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:"type";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:"type";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:"type";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:"type";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:"type";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:"type";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:"type";i:1;s:5:"kName";s:8:"ChonChon";}'; $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:"type";i:1;s:5:"kName";s:5:"Stapo";}'; $string .= '}';
If looked carefully you'll notice in the lines i:0 and i:11 of the vector some spaces between the data that shows what line number and size of data exists.
Upvotes: 1
Views: 777
Reputation: 786291
This should work:
$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";
Update: Since OP likes to have this replacement with single regex only, here is one using negative lookahead:
$str = preg_replace('#\s(?!([^\"]*\"[^\"]*\")*[^\"]*$)#', '_', $str);
echo $str . "\n";
In short this regex finds a space which is NOT followed by even number of double quotes, which means found space is within double quotes hence it is replaced by under-score.
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"
Upvotes: 2
Reputation: 20431
I would avoid using regex if possible, because you can easily unserialize and read the value, then serialize it back. This will ensure that you know exactly what you're changing.
http://www.php.net/manual/en/function.unserialize.php
function space_to_underscore($str) {
return str_replace(' ', '_', $str);
}
Upvotes: 0
Reputation: 4792
Edit: OP has clarified that the string is not a valid serialized object...
I'm not sure if you will be manipulating this object further, or where it came from, but the first thing I would do if it was me is unserialize it (this is making the assumption that you have a serialised object there: it certainly looks like it, although the exact string you posted is not a valid serialized object. I'm making the assumption that you didn't post the whole string).
http://www.php.net/manual/en/function.unserialize.php
Once you have your array in a sensible format you can start applying your transformations on a per attribute basis...
//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);
Performing masses of transformation on attributes of an object/array using regex is just a nightmare - make it easy on yourself and use php native functionality to help you!
If you dont have a serialised object then disregard this answer.
Upvotes: 1