2010-06-18 55 views
11

好吧,我使用perl讀取包含一些常規配置數據的文件。這些數據根據他們的意思組織成標題。一個例子如下:使用perl拆分可能包含空白的行

[vars] 

# This is how we define a variable! 
$var = 10; 
$str = "Hello thar!"; 


# This section contains flags which can be used to modify module behavior 
# All modules read this file and if they understand any of the flags, use them 
[flags] 
    Verbose =  true; # Notice the errant whitespace! 

[path] 
WinPath = default; # Keyword which loads the standard PATH as defined by the operating system. Append with additonal values. 
LinuxPath = default; 

目標:使用第一行作爲「$ VAR = 10;」的一個例子,我想使用在Perl分割函數來創建包含該字符的數組「$變種「和」10「作爲要素。使用另一條線作爲一個例子:

Verbose =   true; 
    # Should become [Verbose, true] aka no whitespace is present 

這是必需的,因爲我將被輸出這些值到一個新的文件(這一條不同的C++代碼將讀取)實例字典對象。只給你的可能是什麼樣子有點味道(只是把它作爲我走):

define new dictionary 
name: [flags] 
# Start defining keys => values 
new key name: Verbose 
new value val: 10 
# End dictionary

哦,這裏是我目前用它做什麼(錯誤地)沿有碼:

sub makeref($) 
{ 
    my @line = (split (/=/)); # Produces ["Verbose", " true"]; 
} 

要回答一個問題,爲什麼我不使用配置::簡單,就是我本來不知道我的配置文件將是什麼樣子,只是我想要它做的事。隨着我走過去 - 至少對我來說似乎是合理的 - 並用perl來解析文件。

問題是我有一些C++代碼會加載配置文件中的信息,但是因爲在C或C++中解析是:(我決定使用perl。這對我來說也是一個很好的學習練習,因爲我是新的這就是事實,這個perl代碼並不是我的應用程序的一部分,它使得C++代碼更容易讀取信息,而且它更易讀(包括配置文件和生成的文件)。感謝您的反饋,它確實幫助。

+1

除非必要,否則請勿使用原型。即使那樣,想想三次。 http://perldoc.perl.org/perlsub.html#Prototypes *當然,這一切都非常強大,只有適度使用才能讓世界變得更美好。* – 2010-06-18 13:11:57

+0

請看FM的回答。你真的不應該編寫自己的文件解析器來完成這樣一個常見的標準作業 - 使用CPAN,並專注於你的應用程序邏輯。 – Ether 2010-06-18 16:42:41

回答

6

如果你這樣做是解析爲一個學習的過程,這很好。但是,CPAN有幾個模塊可以爲您做很多工作。

use Config::Simple; 
Config::Simple->import_from('some_config_file.txt', \my %conf); 
+0

是的,我真的不得不問,爲什麼OP使用與標準配置文件格式非常相似,但不使用標準配置文件讀取器模塊,這些模塊很容易獲得並且經過很好的測試。 (如果Config :: Simple與所需的格式不完全匹配,則YAML是另一個很好的選擇。) – Ether 2010-06-18 16:41:29

+0

95%的時間這是所需的。我有一些原因(學習,不是所有的代碼都在perl中),使它更容易以不同的方式做。 – 2010-06-19 00:29:56

2

好像你已經得到它。分裂之前剝去空格。

sub makeref($) 
{ 
    s/\s+//g; 
    my @line = (split(/=/)); # gets ["verbose", "true"] 
} 
+0

現在它很明顯。謝謝,我是perl的新手,它是一種非常酷的語言。 – 2010-06-18 07:56:06

+0

不客氣。希望能幫助到你。 – 2010-06-18 08:07:30

+0

奇怪的是,chomp不會ch空白! – 2010-06-18 08:17:43

1

這段代碼可以做到這一點(並且在不倒車的情況下效率更高)。對正則表達式

for (@line) { 
    s/^\s+//; 
    s/\s+$//; 
} 
+0

你可以在正則表達式的末尾添加'g'來讓它替換多於一個額外的空白外觀。即's/^ \ s + // g;' – 2010-06-18 08:36:40

+0

請注意混亂的語法高亮。 – Svante 2010-06-18 11:04:39

+0

有許多模塊可以處理CPAN上的配置部分,延續線,多值變量等。一旦你完成學習,使用其中之一。我喜歡'Config :: Std'。 @FM指出'Config :: Simple'。 – 2010-06-18 13:15:23

3

split分割,所以你可以簡單地把空格周圍的=標誌到其正則表達式:

split (/\s*=\s*/, $line); 

你顯然不希望刪除所有空白,或如會產生一條線(字符串中缺少空格):

$str="Hellothere!"; 

我想那個從一開始就和行尾立法院刪除空白就足夠了:

$line =~ s/^\s*(.*?)\s*$/$1/; 

有兩種說法更簡單的選擇:

$line =~ s/^\s+//; 
$line =~ s/\s+$//; 
+0

請注意混亂的語法突出顯示。 – Svante 2010-06-18 11:04:03

+0

這就是爲什麼我在發佈SO時傾向於使用{...} {...}。 – 2010-06-18 13:13:11

+1

's/^ \ s + //'稍微有效一些。 – 2010-06-18 13:16:21

0

你可能已經想通了,但我想我會補充一點。如果你

sub makeref($) 
{ 
    my @line = (split(/=/)); 
    foreach (@line) 
    { 
     s/^\s+//g; 
     s/\s+$//g; 
    } 
} 

然後你將刪除左右兩側的前後空白。這種方式是這樣的:

this is a parameter   =  all sorts of stuff here 

將不會有瘋狂的空間。

!!警告:我可能不知道我在說什麼!