• 3

[研究]正規表示式 Regular Expression的真義~

esouxcon wrote:
比較好奇為什麼一次要...(恕刪)


其實寫程式寫到最後真的會這樣...
越寫就會一直想有沒有更好的寫法
不然其實像這種需求不要用RE做的話, 大概10行以內的小迴圈外帶一個replace就搞定了
難就是難在要用一個指令做完啊
https://jin.tw
Jinwei wrote:
其實寫程式寫到最後真...(恕刪)


這個問題很有趣...想起以前寫過把數字加上逗號的RE
例如:12345678變成12,345,678

這個去掉逗號的問題,我用perl來寫(editplus或ultraedit的RE不會用)
因為每對引號內逗號數目不明,所以用while迴圈重複搜尋刪除逗號
這個RE只會對"成對引號"內的數字才有反應,只有左邊或右邊引號的數字不會被影響
\d等於[0-9]

for $i (<DATA>) {
1 while ($i=~s/("\d+),([\d|,]+",)/$1$2/);
print $i;
}

用程式比較快速,一次解決...
用編輯器比較方便,不能一次解決,那就多取代幾次囉...

Jinwei wrote:
patten的下法是"([0-9,]+)"
這樣就能不管有幾個逗號, 都能抓出引號內的數字
不需要拼成("[0-9]+),([0-9]+)這種
...(恕刪)


依二樓網友的作法
的確是要下("[0-9]+),([0-9]+)這種條件
他的目的不是要找出"XXXXX"這樣的字串

如果是找出字串的方式處理
簡單的下法下(以下是python RE的語法)
".*?"
就可以了
但是如果仔細去看這個數字其實應該是會計格式
(須處理的是超過1000以上的情況才需要)
就需要更準確的下法
假設在沒有小數點的情況下
"-?([0-9]{1,3})(,[0-9]{3})+"
應該可以這樣去表示
可能還有更好的寫法

目前想到的方法除了以match group和程式解決之外
還是想不到有好的解法
卡歐斯 wrote:
依二樓網友的作法的確...(恕刪)


我不太懂耶@@其實我的確是點把這個部分當作半個字串看了^^"
假設最終都要用match group來處理的話
那引號內是不是數字這件事情, 是不是就變的沒有任何意義了???
就是說
"123,456,789" or "999" or "xxxx" 其實就沒差了?
這時候的確".*?"就好了
https://jin.tw
Jinwei 大大說得好
有時候程式寫到最後
真的就會想把它當成是一種藝術!
我想很多會寫程式的大大都會有這種體悟吧!?
本來寫十行
就想說五行可不可以辦到
無形中也會提升自己的功力

感謝所有參與研究的大大
我想古代"以武會友"大概就是這種感覺吧!?
大家互相切磋
互相學習而且互相進步!

其實如果用PHP寫
是早就已經OK的了

但是就是想知道有沒有辦法只用一行RE就可以match到所有的condition

其實引號裡面確實是要數字,只是單純的把逗號拿掉而已。



這是我的解法
把他貼上來跟大家分享
我是用notepad++做的
按CTRL+R會出現Find/Replace視窗
記得勾選右下方的Regular Expr選項及Recurse Repl選項
左中有個Repl&F Again選項
後面可以填入重複次數
把Pattern設好後就可以一次搞定


joenmakiki wrote:
這是我的解法把他貼上...(恕刪)



一次本來搞不定,只能以之前的做法多次替換
只不過替換的工作由軟體自動完成而已
對於程式不是很懂
但小弟用 EmEditor 的寫法是

尋找

「,"([\d]*)([,])」

再用

「,"\1」

進行取代
因為雙引號內之逗號數不一定
所以再跑個迴圈 @@
執行結果
2809,京城銀,"11,220,655",153,"61,230,329",5.35,5.48,5.20,5.46,+,0.19,5.46,2,5.47,12,16.55
2809,京城銀,"11220655",153,"61230329",5.35,5.48,5.20,5.46,+,0.19,5.46,2,5.47,12,16.55

2812,台中銀,"3,294,297",782,"22,636,005",6.96,6.98,6.80,6.95,+,0.25,6.89,10,6.95,12,6.15
2812,台中銀,"3294297",782,"22636005",6.96,6.98,6.80,6.95,+,0.25,6.89,10,6.95,12,6.15

2816,旺旺保,"48,573",23,"336,330",6.99,6.99,6.81,6.95,+,0.24,6.90,1,6.94,2,0.00
2816,旺旺保,"48573",23,"336330",6.99,6.99,6.81,6.95,+,0.24,6.90,1,6.94,2,0.00

2820,華票,"1,690,033",337,"6,838,349",4.04,4.11,3.97,4.01,+,0.04,4.01,121,4.03,1,8.72
2820,華票,"1690033",337,"6838349",4.04,4.11,3.97,4.01,+,0.04,4.01,121,4.03,1,8.72

2832,台產,"379,071",130,"5,360,168",14.30,14.30,14.00,14.25,+,0.25,14.05,2,14.25,6,6.79
2832,台產,"379071",130,"5360168",14.30,14.30,14.00,14.25,+,0.25,14.05,2,14.25,6,6.79

概念很簡單.... 就是用" 分開 然後挑奇數的做替代

程式如下
#!/bin/perl
@a = ('2809,京城銀,"11,220,655",153,"61,230,329",5.35,5.48,5.20,5.46,+,0.19,5.46,2,5.47,12,16.55',
'2812,台中銀,"3,294,297",782,"22,636,005",6.96,6.98,6.80,6.95,+,0.25,6.89,10,6.95,12,6.15',
'2816,旺旺保,"48,573",23,"336,330",6.99,6.99,6.81,6.95,+,0.24,6.90,1,6.94,2,0.00',
'2820,華票,"1,690,033",337,"6,838,349",4.04,4.11,3.97,4.01,+,0.04,4.01,121,4.03,1,8.72',
'2832,台產,"379,071",130,"5,360,168",14.30,14.30,14.00,14.25,+,0.25,14.05,2,14.25,6,6.79');
foreach (@a)
{
print $_,"\n";
$b = $_;
@c = split(/\"/,$b);
$e = $#c;
for($i = 0; $i <= $e ; $i++)
{
if($i%2 == 0){
print $c[$i];
print "\"" ;
next;
}
$d = $c[$i];
$d =~ s/,//g;
print $d;
print "\"";
}
print "\n";
print "\n";
};
Sinc wrote:
執行結果2809,京...(恕刪)


如果這題要動用寫程式來處理, 其實應該不用刻意判斷奇數也可以
畢竟規則很簡單
只要遇到雙引號內的東西, 把逗號拿掉就好了:)
https://jin.tw
  • 3
內文搜尋
X
評分
評分
複製連結
Mobile01提醒您
您目前瀏覽的是行動版網頁
是否切換到電腦版網頁呢?