Marcelo
Marcelo

Reputation: 188

Replace Spaces within "", preg_replace php

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

Answers (3)

anubhava
anubhava

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

Aram Kocharyan
Aram Kocharyan

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

calumbrodie
calumbrodie

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

Related Questions