2013年4月19日 星期五

Regular Expression (RegExp)

        Regular Expression( 以下筆者就簡稱為RegExp)是使用一組字串描述規則,來找符合這個規刖的字串。以一個簡單的例子來說,如果要找一個以AS3開頭的字串的話,就可以寫成^AS3來找到所有以AS3開頭的字串囉。像這種表達規則通常稱為pattern

        本文就簡短的說明一下幾個常見的字元意義
  • ^ 寫在 pattern 第一個位置時,表示其後一符號必須出現在字串開頭的位置。寫在 pattern 中間位置時則為否定之意,表示字串中不可有 ^ 之後一符號的內容。
  • $寫在 pattern 最後一個位置時,表示其前一符號必須出現在字串尾端的位置
  • *表示字串中有 0 到無數個其前一符號的內容。
  • +表示字串中有 1 到無數個其前一符號的內容(至少有一個)。
  • ?表示字串中有 0 到 1個其前一符號的內容。
  • { }表示前一符號在字串中的重覆次數。例如A{2} 表示 'A' 重覆兩次 (即 'AA') ;A{2,}表示字串含有 2 到無數多個 'A' ;A{2,5} 表示含有 2 到 5 個 'A' 。
  • . 表示一個任意字元。
  • [ ]表示字串含有括號中任一字元的內容。可以 - 表示一組連續字元,例如[A-Z]。注意, [] 僅代表一個字元,例如 [ABC]表示 'a' 或 'b' 或 'c' ,而不是 'abc' 
  • \:跳脫字元,例如要表示字串中含有 '/' 字元時,就必須寫成\/
  • |「或」意,字串中含有 '|' 之前一符號或後一符號的內容。例如image\.(jpg|png) 表示 'image.jpg' 或 'image.png' 。通常會用 () 括住 '|' 的前後符號。
  • \d表示任何一個數字,意同 [0-9] 。
  • \D表示任何一個非數字,意同 [^0-9] 。

如果想試試這個功能的,也有網頁版的可以使用

以下為常用的正則表達式
  • 網址:[a-zA-z]+://[^\s]*
  • IP Address:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
  • 時間(小時:分鐘 24小時制):((1|0?)[0-9]|2[0-3]):([0-5][0-9])
  • E-mail:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
  • 日期(年-月-日)(\d{4}|\d{2})-((0?([1-9]))|(1[1|2]))-((0?[1-9])|([12]([1-9]))|(3[0|1]))
  • 日期(月/日/年):((0?[1-9]{1})|(1[1|2]))/(0?[1-9]|([12][1-9])|(3[0|1]))/(\d{4}|\d{2})
  • 正整數:[0-9]*[1-9][0-9]*
  • 非負整數(正整數或零):\d+
  • 負整數:-[0-9]*[1-9][0-9]*
  • 整數:-?\d+
  • 小數:(-?\d+)(\.\d+)?

其它相關的學習資源
http://blog.miniasp.com/post/2008/03/23/Regular-Expression-Regex-Learning-Resources.aspx

[System] 註冊/刪除 Service (使用Command Line)

註冊Windows Service:
        在Command Line下輸入            
C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe ServiceFilePath

ServiceFilePath為實際的服務檔路徑。例:C:\ServiceFile.exe



刪除Windows Service:
        在Command Line下輸入
sc delete ServiceName

ServiceName為服務實際的名稱




取得服務實際的名稱:
        在Command Line下輸入
services.msc

會跳出一個服務的視窗,在想要取得服務名稱的服務上按右鍵後選取內容,就可以在一般的標籤上看到服務名稱了。

如下圖紅色底線所標記












[C#] Windows Service 啟動失敗

        最近在把Console的程式改寫成Windows Service,發現如果在ServiceBase的建構子如果有寫到需要等待的動作才能繼續往下執行程式碼的話。服務就會無法被啟動。

        舉個例子來說明,如果在建構子有以下程式
_TcpListener.AcceptTcpClient()

等待Client的連入,那就會造成服務無沒被啟動。

而解決的方式就是把同步改成非同步的方式來等待Client連入
_TcpListener.BeginAcceptSocket(new AsyncCallback(Accept_Completed), _TcpListener);


後來,我在建構子寫一個空的while(true){}的迴圈來做測試,服務一樣也無法被啟動。

像這種情況下,下指令移除服務,服務是沒有辦法被移除乾淨的。必需要重開機或者登出再登入服務才會真正被移除。



5/6補充:
    在建構子寫AcceptTcpClient()本身就是一個不好的寫法。其實在繼承ServiceBase的類別中去覆寫OnStart(string[] args)的方法,再把原本寫在建構子的程式碼搬到覆寫的方法中就可以了。這個方法會在Service啟動時被呼叫,所以即使是寫_TcpListener.AcceptTcpClient()也不會有任何問題喔!

2013年4月10日 星期三

[C#] abstruct 和 virtual的差別

abstract(抽象方法)和virtual(虛擬方法)主要都是用在父類別中

主要差異在於abstract類似介面(interface)沒有實作為空的方法而其子類別必需複寫(override)實作

而virtual的方法,其子類別就不一定要複寫(override)