2012-03-10 50 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