我試圖創建兩個正則表達式來向字符串中的某些值添加引號。基本上,該字符串會是這樣:正則表達式來匹配任何東西,但超過兩個空格
999 date Doe, John E. London 123456789
我想圍繞名稱,以便如果此文件導出爲CSV,它不會被分開。這是我迄今爲止
$line =~ s/([^\s{2,}]*,[^\s{2,}]*)/"$1"/g;
我覺得應該找到任何逗號和任何靠近它,直到它找到兩個或更多的空間,但它不工作。謝謝您的幫助。
我試圖創建兩個正則表達式來向字符串中的某些值添加引號。基本上,該字符串會是這樣:正則表達式來匹配任何東西,但超過兩個空格
999 date Doe, John E. London 123456789
我想圍繞名稱,以便如果此文件導出爲CSV,它不會被分開。這是我迄今爲止
$line =~ s/([^\s{2,}]*,[^\s{2,}]*)/"$1"/g;
我覺得應該找到任何逗號和任何靠近它,直到它找到兩個或更多的空間,但它不工作。謝謝您的幫助。
你問任何東西除了 2個或更多的空間。
我同意unpack
是更自然的方式來做到這一點。但split
是一種使用圖案形狀的餅乾切割器的方法。任何不是在該模式是一個返回字段。所以這個:
@fields = split /\h{2,}/, $line;
$line = join(" " x 2 => map { "($_)" } @fields);
可能就夠了。
是的,這個工作正常!感謝您的幫助 – atatko 2011-04-26 13:19:24
@atatko:很高興幫助。請注意,我使用'\ h'作爲*水平空白*。這是一個在Perl 5.10中首次出現的新捷徑。在這個版本之前,你必須使用'\ p {HorizSpace}',這個類型很長,人們通常只使用'\ s',同時也得到*垂直空白*(也就是'\ v') 。即使它對一個特定的例子沒有影響,我也喜歡'\ h',因爲它更清楚地說明了我的意思。但是,最好在程序的頂部放置'use 5.10.0;'來表明你需要該程序的最低版本號才能正常工作。 – tchrist 2011-04-26 13:26:17
[]
包含允許的字符範圍,2-space不是字符。
可能:
$line =~ s/ (.*? .*?)/"\1" /g;
你可能需要更明確的瞭解,以避免對'匹配的格式。
$line =~ s/ (\w+?, [\w ]+?.)/"\1" /g;
爲了避免在更換重複的空間,環視可以用來斷言,這也可以解決在該行的開始和結束的項目問題:
$line =~ s/(?<=^| )(\w+?, [\w ]+?.)(?=$| )/"\1"/g;
而且是小心你的原始格式 - 你確定它不只是列對齊? (在這種情況下,足夠長的名稱或日期可能不允許列之間有2+空格)。
試試這個:
s/.* \K(.*),(.*?) /"$1,$2"/
從邏輯上講,這意味着:查找兩個空格和逗號,其中兩個空間的最右端,然後是逗號和兩個空間之間的子串之間的串,子字符儘可能短。
你的方法也可以工作,如果你有正確的消極lookaheads的語法。
您提供的示例文本似乎被製表符或空格分隔(列對齊?)。知道哪個或正則表達式不起作用很重要。知道該模式在整個文件中是否一致也很重要。
如果按列對齊,最簡單也可能最安全的方法是簡單地對字符進行計數。例如。:
s/(^.{20})(\S*) /$1"$2"/;
(你將不得不調整自己的20號我只是近似。)
注意,我在名字字段的一個魯莽的方式結束斬去兩個空格。這是爲了不把以下值的格式搞亂。但是如果字段填滿了邊緣,最後可能沒有兩個空格,並且正則表達式將會丟失。但是,另一方面,您無論如何都無法適應報價。
在處理這些類型的文件時,我不認爲使用泛型搜索是安全的。如果你指望逗號只出現在名字中,遲早你會發現有人認爲「紐約布朗克斯」應該在城市場地,並且你的正則表達式會被搞砸。
一個稍微更加嚴格,但複雜的正則表達式將包括上述字段:
$date='\d{2}-\d{2}-\d{2}'; # this might work for dates such as 11-10-23
s/^(\d+\s+$date\s+)(\S+) /$1"$2"/;
同樣在這裏的事情,如果名稱字段是不是足夠大,以適應兩個引號,它不會被添加。你應該檢查你的文件,看看是否有這種情況。如果是這樣,你需要以某種方式處理它。
我有時會發現,將某些字段的正則表達式放入單獨的變量中會有助於提高可讀性,例如上面的$ date。
祝你好運!
你的「紐約布朗克斯」的例子正是爲什麼這需要更動態地工作。我的第一個例子可能過於簡單,任何一個字段都可以包含一個逗號,而當它們執行時,它應該被引號包圍。 – atatko 2011-04-26 13:10:59
你不能把量詞放在這些方括號內的字符類中。他們無法將其量化爲非人。 – tchrist 2011-04-26 12:52:37
@tchrist我之前使用過這個方法,但沒有使用限定括號'{}'。你可以用這個來返回xml括號後面的所有內容,例如,像這樣:'[^ <>] *)/' – atatko 2011-04-26 13:01:30
方括號。 – tchrist 2011-04-26 13:02:35