2012-04-20 44 views
0

我需要重構跨多個文件夾中存儲的多個PHP文件的一些代碼。正則表達式搜索和替換多個文件

我需要更換喜歡的代碼實例:

trim(ucfirst($userinfo['first_name'])).' '.trim(ucfirst($userinfo['last_name'])) 

對於文本(的地方,在這些文件中)爲:

formatUserName($userinfo['first_name'],$userinfo['last_name']) 

注意,$變量名會有所不同,但一切否則將是相同的*。

我在一臺Windows機器上,但安裝了PHP和Perl - 寧願使用它而不是sed。

我有Notepad ++,但不知道是否可以處理這樣的搜索和替換操作。

*我們的代碼中有這樣一行代碼的變體,一旦我理解了如何構建正確的正則表達式,我將自行嘗試。

+2

什麼是你的問題? – TLP 2012-04-20 12:47:38

+2

我們在談論多少個文件?如果是在合理的範圍內,你可以簡單地使用一個編輯器,讓你創建一個項目(向其中添加所有文件),並在項目中的所有文件上運行查找和替換(我使用PSPad)。然後在名稱變量上查找,以檢查是否更新了此問題的所有實例。 – Armatus 2012-04-20 12:48:04

+0

@將 - 這是一個編程問題 - 我試圖確定使用適當的正則表達式。 – siliconpi 2012-04-21 01:12:23

回答

1

用記事本++ 6.0的版本,你可以這樣做:

查找:formatUserName\(\1,\2\)

+0

我認爲它需要是formatUserName(\ 1,\ 2) – siliconpi 2012-04-20 13:16:29

+0

@SidB:良好的捕獲,回答編輯。 – Toto 2012-04-20 13:19:37

+0

它工作真棒......! :D – siliconpi 2012-04-20 13:36:30

0

我假設你的問題是關於如何處理元字符。這是一種方法。

my $find = q|trim(ucfirst($userinfo['first_name'])).' '.trim(ucfirst($userinfo['last_name']))|; 
my $replace = q|formatUserName($userinfo['first_name'],$userinfo['last_name'])|; 

while (<>) { 
    s/\Q$find\E/$replace/g; 
} 

\Q ... \E將導致正則表達式匹配裏面是什麼,它確實,雖然變數仍然插值。

+0

問題說變量名稱是不同的。 – daxim 2012-04-20 13:04:00

+0

@daxim這個問題說了很多東西。我回答了關於元字符的部分。 – TLP 2012-04-20 13:08:41

+0

是的,變量名稱$ userinfo將是$ admininfo,$ insinfo等等。但是它將在'first_name'和'last_name'之間相同。 – siliconpi 2012-04-20 13:08:56

0

未經測試(沒有Windows外殼可用):

perl -i.bak -lpe"BEGIN { $varname = qr/\$[a-z]+/; } s/trim\(ucfirst\(($varname)\['first_name'\]\)\)\.' '\.trim\(ucfirst\(\1\[\'last_name'\]\)\)/formatUserName($1['first_name'],$1['last_name'])/;" file1.php file2.php file3.php … 

注意trim\(ucfirst\((\$\w+\['first_name'\])\)\)\.' '\.trim\(ucfirst\((\$\w+\['last_name'\])\)\)

與更換\1 backref在匹配部分和$1捕獲緩衝區在subst部分。

+1

Windows外殼不會自動爲您設置參數。另外WIndows Perl不會讓你在沒有備份文件的情況下進行就地編輯:你需要'-i.bak'或類似的文件。 – Borodin 2012-04-20 13:11:32

0

腳本:

$_ = 'trim(ucfirst($userinfo[\'first_name\'])).\' \'.trim(ucfirst($userinfo[\'last_name\']))'; 
s/^trim\(ucfirst\((\$[^\)]+)\)\)\.'\s+'\.trim\(ucfirst\((\$[^\)]+)\)\)$/formatUserName($1,$2)/; 
print $_; 

輸出:

formatUserName($userinfo['first_name'],$userinfo['last_name']) 

測試環節:http://ideone.com/4e0Bf

0

也許是最好的辦法是使用File::Find模塊來填充@ARGV,然後只需在while (<>)循環內進行替換。

該程序顯示的想法,但我沒有測試過正則表達式,所以要小心。這些文件的備份副本將被保存爲*.php.bak

use strict; 
use warnings; 

use File::Find; 

our @ARGV =(); 

find sub { 
    push @ARGV, $File::Find::name if /\.php$/; 
}, 'C:\path\to\tree\root'; 

$^I = '.bak'; 

while (<>) { 
    s<\Qtrim(ucfirst(\E\$(\w+)\Q['first_name'])).' '.trim(ucfirst(\E\$\1\Q['last_name']))\E> 
    <formatUserName(\$$1['first_name'],\$$1['last_name'])>g; 
    print; 
}