• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            C++ Jounior

            once setback,once inspiration,once self-awareness
            重要的是這個磨練過程,而不是結果,要的是你粗壯的腿,而不是你身上背的那袋鹽巴

             

            銀行家算法

                 摘要: reference ; http://www.yuanma.org/data/2008/0116/article_2945.htm算法的實現 一、初始化 由用戶輸入數據,分別對可利用資源向量矩陣AVAILABLE、最大需求矩陣MAX、分配矩陣ALLOCATION、需求矩陣NEED賦值。 ? 二、銀行家算法 在避免死鎖的方法中,所施加的限制條件較弱,有可能獲得令人滿意的系統性...  閱讀全文

            posted @ 2008-07-06 22:16 snowball 閱讀(6784) | 評論 (8)編輯 收藏

            面向對象的三個基本特征(講解)

                 摘要: 面向對象的三個基本特征(講解) 面向對象的三個基本特征是:封裝、繼承、多態。 ...  閱讀全文

            posted @ 2008-07-01 16:10 snowball 閱讀(10298) | 評論 (6)編輯 收藏

            電子書下載

            Inside Microsoft Dynamics AX 4.0 Link

            posted @ 2008-04-11 16:04 snowball 閱讀(343) | 評論 (0)編輯 收藏

            初學者,你應當如何學習C++以及編程

            JavaScript是世界上最受誤解的語言,其實C++何嘗不是。坊間流傳的錯誤的C++學習方法一抓就是一大把。我自己在學習C++的過程中也走了許多彎路,浪費了不少時間。

              為什么會存在這么多錯誤認識?原因主要有三個,一是C++語言的細節太多。二是一些著名的C++書籍總在(不管有意還是無意)暗示語言細節的重要性和有趣。三是現代C++庫的開發哲學必須用到一些犄角旮旯的語言細節(但注意,是庫設計,不是日常編程)。這些共同塑造了C++社群的整體心態和哲學。

              單是第一條還未必能夠成氣候,其它語言的細節也不少(盡管比起C++起來還是小巫見大巫),就拿javascript來說,作用域規則,名字查找,closure,for/in,這些都是細節,而且其中還有違反直覺的。但許多動態語言的程序員的理念我猜大約是學到哪用到哪罷。但C++就不一樣了,學C++之人有一種類似于被暗示的潛在心態,就是一定要先把語言核心基本上吃透了才能下手寫出漂亮的程序。這首先就錯了。這個意識形成的原因在第二點,C++書籍。市面上的C++書籍不計其數,但有一個共同的缺點,就是講語言細節的書太多——《C++ gotchas》,《Effective C++》,《More Effective C++》,但無可厚非的是,C++是這樣一門語言:要拿它滿足現代編程理念的需求,尤其是C++庫開發的需求,還必須得關注語言細節,乃至于在C++中利用語言細節已經成了一門學問。比如C++模板在設計之初根本沒有想到模板元編程這回事,更沒想到C++模板系統是圖靈完備的,這也就導致了《Modern C++ Design》和《C++ Template Metaprogramming》的驚世駭俗。

              這些技術的出現為什么驚世駭俗,打個比方,就好比是一塊大家都認為已經熟悉無比,再無秘密可言的土地上,突然某天有人挖到原來地下還蘊藏著最豐富的石油。在這之前的C++雖然也有一些細節,但也還算容易掌握,那可是C++程序員們的happy old times,因為C++的一切都一覽無余,everything is figured out。然而《Modern C++ Design》的出世告訴人們,“瞧,還有多少細節你們沒有掌握啊。”于是C++程序員們久違的激情被重燃起來,奮不顧身的踏入細節的沼澤中。尤其是,模板編程將C++的細節進一步挖掘到了極致——我們干嘛關心涉及類對象的隱式轉換的優先級高低?看看boost::is_base_of就可以知道有多詭異了。

              但最大的問題還在于,對于這些細節的關注還真有它合適的理由:我們要開發現代模板庫,要開發active library,就必須動用模板編程技術,要動用模板編程技術,就必須利用語言的犄角旮旯,enable_if,type_traits,甚至連早就古井無波的C宏也在亂世中重生,看看boost::preprocessor有多詭異就知道了,連C宏的圖靈完備性(預編譯期的)都被挖掘出來了。為什么要做這些?好玩?標榜?都不是,開發庫的實際需求。但這也正是最大的悲哀了。在boost里面因實際需求而動用語言細節最終居然能神奇的完成任務的最好教材就是boost::foreach,這個小設施對語言細節的發掘達到了驚天地泣鬼神的地步,不信你先試著自己去看看它的源代碼,再看看作者介紹它的文章吧。而boost::typeof也不甘其后——C++語言里面有太多被“發現”而不是被“發明”的技術。難道最初無意設置這些語言規則的家伙們都是Oracles?

              因為沒有variadic templates,人們用宏加上缺省模板參數來實現類似效果。因為沒有concepts,人們用模板加上析構函數的細節來完成類似工作。因為沒有typeof,人們用模板元編程和宏加上無盡的細節來實現目標… C++開發者們的DIY精神不可謂不強。

              然而,如果僅僅是因為要開發優秀的庫,那么涉及這些細節都還是情有可原的,至少在C++09出現并且編譯器廠商跟上之前,這些都還能說是不得已而為之。但我們廣大的C++程序員呢?大眾是容易被誤導的,我也曾經是。以為掌握了更多的語言細節就更牛,但實際卻是那些語言細節十有八九是平時編程用都用不到的。C++中眾多的細節雖然在庫設計者手里面有其用武之地,但普通程序員則根本無需過多關注,尤其是沒有實際動機的關注。一般性的編碼實踐準則,以及基本的編程能力和基本功,乃至基本的程序設計理論以及算法設計。才是真正需要花時間掌握的東西。

              學習最佳編碼實踐比學習C++更重要。看優秀的代碼也比埋頭用差勁的編碼方式寫垃圾代碼要有效。直接、清晰、明了、KISS地表達意圖比玩編碼花招要重要…

              避免去過問任何語言細節,除非必要。這個必要是指在實際編程當中遇到問題,這樣就算需要過問細節,也是最省事的,懶惰者原則嘛。一個掌握了基本的編程理念并有較強學習能力的程序員在用一門陌生的語言編程時就算拿著那本語言的圣經從索引翻起也可以編出合格的程序來。十年學會編程不是指對每門語言都得十年,那一輩子才能學幾門語言哪,如果按字母順序學的話一輩子都別指望學到Ruby了;十年學習編程更不是指先把語言特性從粗到細全都吃透才敢下手編程,在實踐中提高才是最重要的。

              至于這種摳語言細節的哲學為何能在社群里面呈野火燎原之勢,就是一個心理學的問題了。想像人們在論壇上討論問題時,一個對語言把握很細致的人肯定能夠得到更多的佩服,而由于論壇上的問題大多是小問題,所以解決實際問題的真正能力并不能得到顯現,也就是說,知識型的人能夠得到更多佩服,后者便成為動力和仿效的砝碼。然而真正的編程能力是與語言細節沒關系的,熟練運用一門語言能夠幫你最佳表達你的意圖,但熟練運用一門語言絕不意味著要把它的邊邊角角全都記住。懂得一些常識,有了編程的基本直覺,遇到一些細節錯誤的時候再去查書,是最節省時間的辦法。

              C++的書,Bjarne的圣經《The C++ Programming Language》是高屋建瓴的。《大規模C++程序設計》是挺務實的。《Accelerated C++》是最佳入門的。《C++ Templates》是僅作參考的。《C++ Template Metaprogramming》是精力過剩者可以玩一玩的,普通程序員碰都別碰的。《ISO.IEC C++ Standard 14882》不是拿來讀的。Bjarne最近在做C++的教育,新書是絕對可以期待的。

              P.S. 關于如何學習編程,g9的blog上有許多精彩的文章:這里,這里,這里,這里… 實際上,我建議你去把g9老大的blog翻個底朝天 :P

              再P.S. 書單?我是遑于給出一個類似《C++初學者必讀》這種書單的。C++的書不計其數,被公認的好書也不勝枚舉。只不過有些書容易給初學者造成一種錯覺,就是“學習C++就應該是這個樣子的”。比如有朋友提到的《高質量C/C++編程》,這本書有價值,但不適合初學者,初學者讀這樣的書容易一葉障目不見泰山。實際上,正確的態度是,細節是必要的。但細節是次要的。其實學習編程我覺得應該最先學習如何用偽碼表達思想呢,君不見《Introduction to Algorithm》里面的代碼?《TAOCP》中的代碼?哦,對了它們是自己建立的語言,但這種僅教學目的的語言的目的就是為了避免讓寫程序的人一開始就忘了寫程序是為了完成功能,以為寫程序就是和語言細節作斗爭了。Bjarne說程序的正確性最重要,boost的編碼標準里面也將正確性列在性能前面。

              此外,一旦建立了正確的學習編程的理念,其實什么書(只要不是太垃圾的)都有些用處。都當成參考書,用的時候從目錄或索引翻,基本就對了。

              再再P.S. myan老大和g9老大都給出了許多精彩的見解。我不得不再加上一個P.S。具體我就不摘錄了,如果你讀到這里,請務必往下看他們的評論。轉載者別忘了轉載他們的評論:-)

              許多朋友都問我同一個問題,到底要不要學習C++。其實這個問題問得很沒有意義。“學C++”和“不學C++”這個二分法是沒意義的,為什么?因為這個問題很表面,甚至很浮躁。重要的不是你掌握的語言,而是你掌握的能力,借用myan老大的話,“重要的是這個磨練過程,而不是結果,要的是你粗壯的腿,而不是你身上背的那袋鹽巴。”。此外學習C++的意義其實真的是醉翁之意不在酒,像C/C++這種系統級語言,在學習的過程中必須要涉及到一些底層知識,如內存管理、編譯連接系統、匯編語言、硬件體系結構等等等等知識(注意,這不包括過分犄角旮旯的語言枝節)。這些東西也就是所謂的內功了(其實最最重要的內功還是長期學習所磨練出來的自學能力)。對此大嘴Joel在《Joel On Software》里面提到的漏洞抽象定律闡述得就非常漂亮。

              所以,答案是,讓你成為高手的并不是你掌握什么語言,精通C++未必就能讓你成為高手,不精通C++也未必就能讓你成為低手。我想大家都不會懷疑g9老大如果要抄起C++做一個項目的話會比大多數自認熟練C++的人要做得漂亮。所以關鍵的不是語言這個表層的東西,而是底下的本質矛盾。當然,不是說那就什么語言都不要學了,按照一種曹操的邏輯,“天下語言,唯imperative與declarative耳”。C++是前者里面最復雜的一種,支持最廣泛的編程范式。借用當初數學系入學大會上一個老師的話,“你數學都學了,還有什么不能學的呢?”。學語言是一個途徑,如果你把它用來磨練自己,可以。如果你把它用來作為學習系統底層知識的鑰匙,可以。如果你把它用來作為學習如何編寫優秀的代碼,如何組織大型的程序,如何進行抽象設計,可以。如果掉書袋,光啃細節,我認為不可以(除非你必須要用到細節,像boost庫的coder們)。

            然后再借用一下g9老大的《銀彈和我們的職業》中的話:

              銀彈和我們的職業發展有什么相干?很簡單:我們得把時間用于學習解決本質困難。新技術給高手帶來方便。菜鳥們卻不用指望被新技術拯救。沿用以前的比喻, 一流的攝影師不會因為相機的更新換代而丟掉飯碗,反而可能借助先進技術留下傳世佳作。因為攝影的本質困難,還是攝影師的藝術感覺。熱門技術也就等于相機。 不停追新,學習這個框架,那個軟件,好比成天鉆研不同相機的說明書。而熱門技術后的來龍去脈,才好比攝影技術。為什么推出這個框架?它解決了什么其它框架 不能解決的問題?它在哪里適用?它在哪里不適用?它用了什么新的設計?它改進了哪些舊的設計?Why is forever. 和 朋友聊天時提到Steve McConnell的《Professional Software Development》里面引了一個調查,說軟件開發技術的半衰期20年。也就是說20年后我們現在知識里一半的東西過時。相當不壞。朋友打趣道:“應 該說20年后IT界一半的技術過時,我們學的過時技術遠遠超過這個比例。具體到某人,很可能5年他就廢了”。話雖悲觀,但可見選擇學習內容的重要性。學習 本質技藝(技術遲早過時,技藝卻常用長新)還有一好處,就是不用看著自己心愛的技術受到挑戰的時候干嚎。C/C++過時就過時了唄,只要有其它的系統編程 語言。Java倒了就倒了唄,未必我不能用.net?Ruby曇花一現又如何。如果用得不爽,換到其它動態語言就是了。J2EE被廢了又怎樣?未必我們就 做不出分布系統了?這里還舉了更多的例子。

              一句話,只有人是真正的銀彈。職業發展的目標,就是把自己變成銀彈。那時候,你就不再是人,而是人彈。

              最后就以我在Bjarne的眾多訪談當中摘錄的一些關于如何學習C++(以及編程)的看法結束吧(沒空逐段翻譯了,只將其中我覺得最重要的幾段譯了一下,當然,其它也很重要,這些段落是在Bjarne的所有采訪稿中摘抄出來的,所以強烈建議都過目一下):

              I suspect that people think too little about what they want to build, too little about what would make it correct, and too much about "efficiency" and following fashions of programming style. The key questions are always: "what do I want to do?" and "how do I know that I have done if?". Strategies for testing enters into my concerns from well before I write the firat line of code, and that despite my view that you have to write code very early - rather than wait until a design is complete.

              譯:我感覺人們過多關注了所謂“效率”以及跟隨編程風格的潮流,卻嚴重忽視了本不該被忽視的問題,如“我究竟想要構建什么樣的系統”、“怎樣才能使它正確”。最關鍵的問題永遠是:“我究竟想要做什么?”和“如何才能知道我的系統是否已經完成了呢?”就拿我來說吧,我會在編寫第一行代碼之前就考慮測試方案,而且這還是在我關于應當早于設計完成之前就進行編碼的觀點的前提之下。

              Obviously, C++ is very complex. Obviously, people get lost. However, most peple get lost when they get diverted into becoming language lawyers rather than getting lost when they have a clear idea of what they want to express and simply look at C++ language features to see how to express it. Once you know data absreaction, class hierarchies (object-oriented programming), and parameterization with types (generic programming) in a fairly general way, the C++ language features fall in place.

              譯:誠然,C++非常復雜。誠然,人們迷失其中了。然而問題是,大多數人不是因為首先對自己想要表達什么有了清晰的認識只不過在去C++語言中搜尋合適的語言特性時迷失的,相反,大多數人是在不覺成為語言律師的路上迷失在細節的叢林中的。事實是,只需對數據抽象、類體系結構(OOP)以及參數化類型(GP)有一個相當一般層面的了解,C++紛繁的語言特性也就清晰起來了。

              Well, I don't think I made such a trade-off. I want elegant and efficient code. Sometimes I get it. These dichotomies (between efficiency versus correctness, efficiency versus programmer time, efficiency versus high-level, et cetera.) are bogus.

              I think the real problem is that "we" (that is, we software developers) are in a permanent state of emergency, grASPing at straws to get our work done. We perform many minor miracles through trial and error, excessive use of brute force, and lots and lots of testing, but--so often--it's not enough.

              Software developers have become adept at the difficult art of building reasonably reliable systems out of unreliable parts. The snag is that often we do not know exactly how we did it: a system just "sort of evolved" into something minimally acceptable. Personally, I prefer to know when a system will work, and why it will.

              There are more useful systems developed in languages deemed awful than in languages praised for being beautiful--many more. The purpose of a programming language is to help build good systems, where "good" can be defined in many ways. My brief definition is, correct, maintainable, and adequately fast. Aesthetics matter, but first and foremost a language must be useful; it must allow real-world programmers to express real-world ideas succinctly and affordably.

              I'm sure that for every programmer that dislikes C++, there is one who likes it. However, a friend of mine went to a conference where the keynote speaker asked the audience to indicate by show of hands, one, how many people disliked C++, and two, how many people had written a C++ program. There were twice as many people in the first group than the second. Expressing dislike of something you don't know is usually known as prejudice. Also, complainers are always louder and more certain than proponents--reasonable people acknowledge flaws. I think I know more about the problems with C++ than just about anyone, but I also know how to avoid them and how to use C++'s strengths.

              In any case, I don't think it is true that the programming languages are so difficult to learn. For example, every first-year university biology textbook contains more details and deeper theory than even an expert-level programming-language book. Most applications involve standards, operating systems, libraries, and tools that far exceed modern programming languages in complexity. What is difficult is the appreciation of the underlying techniques and their application to real-world problems. Obviously, most current languages have many parts that are unnecessarily complex, but the degree of those complexities compared to some ideal minimum is often exaggerated.

              We need relatively complex language to deal with absolutely complex problems. I note that English is arguably the largest and most complex language in the world (measured in number of words and idioms), but also one of the most successful.

              C++ provides a nice, extended case study in the evolutionary approach. C compatibility has been far harder to maintain than I or anyone else expected. Part of the reason is that C has kept evolving, partially guided by people who insist that C++ compatibility is neither necessary nor good for C. Another reason-- probably even more important--is that organizations prefer interfaces that are in the C/C++ subset so that they can support both languages with a single effort. This leads to a constant pressure on users not to use the most powerful C++ features and to myths about why they should be used "carefully," "infrequently," or "by experts only." That, combined with backwards-looking teaching of C++, has led to many failures to reap the potential benefits of C++ as a high-level language with powerful abstraction mechanisms.

              The question is how deeply integrated into the application those system dependencies are. I prefer the application to be designed conceptually in isolation from the underlying system, with an explicitly defined interface to "the outer world," and then integrated through a thin layer of interface code.

              Had I had a chance to name the style of programming I like best, it would have been "class-oriented programming", but then I'm not particularly good at finding snappy names. The school of thought that I belong to - rooted in Simula and related design philosophies - emphasizes the role of compile-time checking and flexible (static) type systems. Reasoning about the behavior of a program has to be rooted in the (static) structure of the source code. The focus should be on guarantees, invariant, etc. which are closely tied to that static structure. This is the only way I know to effectively deal with correctness. Testing is essential but cannot be systematic and complete without a good internal program structure - simple-minded blackbox testing of any significant system is infeasible because of the exponential explosion of states.

              So, I recommend people to think in terms of class invariants, exception handling guarantees, highly structured resource management, etc. I should add that I intensely dislike debugging (as ah hoc and unsystematic) and strongly prefer reasoning about source code and systematic testing.

              Pros: flexibility, generality, performance, portability, good tool support, available on more platforms than any competitor except C, Access to hardware and system resources, good availability of programmers and designers. Cons: complexity, sub-optimal use caused by poor teaching and myths.

            ?

            posted @ 2008-04-06 12:07 snowball 閱讀(2010) | 評論 (4)編輯 收藏

            C++中的內存劃分

            在C++中,內存分成5個區,他們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。

              棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變量的存儲區。里面的變量通常是局部變量、函數參數等。

              堆,就是那些由new分配的內存塊,他們的釋放編譯器不去管,由我們的應用程序去控制,一般一個new就要對應一個delete。如果程序員沒有釋放掉,那么在程序結束后,操作系統會自動回收。

              自由存儲區,就是那些由malloc等分配的內存塊,他和堆是十分相似的,不過它是用free來結束自己的生命的。

              全局/靜態存儲區,全局變量和靜態變量被分配到同一塊內存中,在以前的C語言中,全局變量又分為初始化的和未初始化的,在C++里面沒有這個區分了,他們共同占用同一塊內存區。

              常量存儲區,這是一塊比較特殊的存儲區,他們里面存放的是常量,不允許修改(當然,你要通過非正當手段也可以修改,而且方法很多)

            ?

            posted @ 2008-04-06 12:02 snowball 閱讀(355) | 評論 (1)編輯 收藏

            Memset ,memcpy,strcpy 區別

            Memset 用來對一段內存空間全部設置為某個字符,一般用在對定義的字符串進行初始化為 ‘ ’ ‘\0’

            :char a[100];memset(a, '\0', sizeof(a));

            ??? memset 可以方便的清空一個結構類型的變量或數組。

            如:

            struct sample_struct
            {
            char csName[16];
            int iSeq;
            int iType;
            };

            對于變量
            struct sample_strcut stTest;

            一般情況下,清空 stTest 的方法:

            stTest.csName[0]='\0';
            stTest.iSeq=0;
            stTest.iType=0;

            memset 就非常方便:
            memset(&stTest,0,sizeof(struct sample_struct));

            如果是數組:

            struct sample_struct TEST[10];

            memset(TEST,0,sizeof(struct sample_struct)*10);

            memcpy 用來做內存拷貝,你可以拿它拷貝任何數據類型的對象,可以指定拷貝的數據長度。

            例: char a[100],b[50]; memcpy(b, a, sizeof(b)); 注意如用 sizeof(a) ,會造成 b 的內存地址溢出。

            Strcpy?? 就只能拷貝字符串了,它遇到 '\0' 就結束拷貝。

            例: char a[100],b[50];strcpy(a,b); 如用 strcpy(b,a) ,要注意 a 中的字符串長度(第一個 ‘\0’ 之前)是否超過 50 位,如超過,則會造成 b 的內存地址溢出。

            str 也可以用用個參數的 strncpy(a,b,n)

            ========================================================

            memset 主要應用是初始化某個內存空間。
            memcpy
            是用于 copy 源空間的數據到目的空間中。
            strcpy
            用于字符串 copy, 遇到 ‘\0’ ,將結束。

            如果你理解了這些,你應該知道他們的區別:例如你初始化某塊空間的時候,用到 memcpy ,那么應該怎么寫,是不是顯得很笨。
            int m[100]
            memset((void*)m,0x00,sizeof(int)*100);//Ok

            memcpy((void*)m,"\0\0\0\0....",sizeof(int)*100);//it’s wrong.
            reference : http://hi.baidu.com/%B5%CE%C9%B3/blog/item/12025c2af5ffc33c5343c19f.html

            posted @ 2008-04-06 10:31 snowball 閱讀(407) | 評論 (0)編輯 收藏

            高效人士的做事方法

            1.主動獲得工作計劃,達到在全局思維上對自已所做的事情有一個主動的感覺。(比如相關的文檔,web 連接,聯系人,相關術語)
            2.鍛練身體(跑步,太極拳)
            3.學習英語(晨讀,聽力)

            posted @ 2008-04-03 08:55 snowball 閱讀(281) | 評論 (0)編輯 收藏

            .net中的正則表達式使用高級技巧

                 摘要: reference :http://www.cnblogs.com/thinhunan/archive/2007/08/21/339316.html.net中的正則表達式使用高級技巧 前言 ...  閱讀全文

            posted @ 2008-04-02 13:42 snowball 閱讀(509) | 評論 (0)編輯 收藏

            C#正則表達式整理備忘

                 摘要: reference :http://www.cnblogs.com/KissKnife/archive/2008/03/23/1118423.html有一段時間,正則表達式學習很火熱很潮流,當時在CSDN一天就能看到好幾個正則表達式的帖子,那段時間借助論壇以及Wrox Press出版的《C#字符串和正則表達式參考手冊》學習了一些基礎的知識,同時也為我在CSDN大概賺了1000分,今天想起來,去找《...  閱讀全文

            posted @ 2008-04-02 13:40 snowball 閱讀(321) | 評論 (0)編輯 收藏

            解讀C#中的規則表達式[轉]

            reference : http://www.chinaaspx.com/Comm/Dotnetbbs/Showtopic.aspx?Forum_ID=5&Id=5250&Page=1
            多少年來,許多的編程語言和工具都包含對規則表達式的支持,.NET基礎類庫中包含有一個名字空間和一系列可以充分發揮規則表達式威力的類,而且它們也都與未來的Perl 5中的規則表達式兼容。?

              此外,regexp類還能夠完成一些其他的功能,例如從右至左的結合模式和表達式的編輯等。?

              在這篇文章中,我將簡要地介紹System.Text.RegularExpression中的類和方法、一些字符串匹配和替換的例子以及組結構的詳細情況,最后,還會介紹一些你可能會用到的常見的表達式。?

            應該掌握的基礎知識?
              規則表達式的知識可能是不少編程人員“常學常忘”的知識之一。在這篇文章中,我們將假定你已經掌握了規則表達式的用法,尤其是Perl 5中表達式的用法。.NET的regexp類是Perl 5中表達式的一個超集,因此,從理論上說它將作為一個很好的起點。我們還假設你具有了C#的語法和.NET架構的基本知識。?

              如果你沒有規則表達式方面的知識,我建議你從Perl 5的語法著手開始學習。在規則表達式方面的權威書籍是由杰弗里·弗雷德爾編寫的《掌握表達式》一書,對于希望深刻理解表達式的讀者,我們強烈建議閱讀這本書。?

            RegularExpression組合體?
              regexp規則類包含在System.Text.RegularExpressions.dll文件中,在對應用軟件進行編譯時你必須引用這個文件,例如,csc r:System.Text.RegularExpressions.dll foo.cs命令將創建foo.exe文件,它就引用了System.Text.RegularExpressions文件。?

            名字空間簡介?
              在名字空間中僅僅包含著6個類和一個定義,它們是:?

              Capture: 包含一次匹配的結果;?

              CaptureCollection: Capture的序列;?

              Group: 一次組記錄的結果,由Capture繼承而來;?

              Match: 一次表達式的匹配結果,由Group繼承而來;?

              MatchCollection: Match的一個序列;?

              MatchEvaluator: 執行替換操作時使用的代理;?

              Regex:編譯后的表達式的實例。?

              Regex類中還包含一些靜態的方法:?

              Escape: 對字符串中的regex中的轉義符進行轉義;?

              IsMatch: 如果表達式在字符串中匹配,該方法返回一個布爾值;?

              Match: 返回Match的實例;?

              Matches: 返回一系列的Match的方法;?

              Replace: 用替換字符串替換匹配的表達式;?

              Split: 返回一系列由表達式決定的字符串;?

              Unescape:不對字符串中的轉義字符轉義。?

            簡單匹配?
              我們首先從使用Regex、Match類的簡單表達式開始學習。?

              Match m = Regex.Match("abracadabra", "(a|b|r)+");?

              我們現在有了一個可以用于測試的Match類的實例,例如:if (m.Success)...?

              如果想使用匹配的字符串,可以把它轉換成一個字符串:?

              Console.WriteLine("Match="+m.ToString());?

              這個例子可以得到如下的輸出: Match=abra。這就是匹配的字符串了。?

            字符串的替換?
              簡單字符串的替換非常直觀。例如下面的語句:?

              string s = Regex.Replace("abracadabra", "abra", "zzzz");?

              它返回字符串zzzzcadzzzz,所有匹配的字符串都被替換成了zzzzz。?

              現在我們來看一個比較復雜的字符串替換的例子:?

              string s = Regex.Replace(" abra ", @"^\s*(.*?)\s*$", "$1");?

              這個語句返回字符串abra,其前導和后綴的空格都去掉了。?

              上面的模式對于刪除任意字符串中的前導和后續空格都非常有用。在C#中,我們還經常使用字母字符串,在一個字母字符串中,編譯程序不把字符“ \” 作為轉義字符處理。在使用字符“\”指定轉義字符時,@"..."是非常有用的。另外值得一提的是$1在字符串替換方面的使用,它表明替換字符串只能包含被替換的字符串。?

            匹配引擎的細節?
              現在,我們通過一個組結構來理解一個稍微復雜的例子。看下面的例子:?

              string text = "abracadabra1abracadabra2abracadabra3";?

              string pat = @"?

                ( # 第一個組的開始?

                 abra # 匹配字符串abra?

                 ( # 第二個組的開始?

                 cad # 匹配字符串cad?

                 )? # 第二個組結束(可選)?

                ) # 第一個組結束?

                + # 匹配一次或多次?

                ";?

              //利用x修飾符忽略注釋?

              Regex r = new Regex(pat, "x");?

              //獲得組號碼的清單?

              int[] gnums = r.GetGroupNumbers();?

              //首次匹配?

              Match m = r.Match(text);?

              while (m.Success)?

               {?

              //從組1開始?

               for (int i = 1; i < gnums.Length; i++)?

                {?

                Group g = m.Group(gnums[i]);?

              //獲得這次匹配的組?

                Console.WriteLine("Group"+gnums[i]+"=["+g.ToString()+"]");?

              //計算這個組的起始位置和長度?

                CaptureCollection cc = g.Captures;?

                for (int j = 0; j < cc.Count; j++)?

                 {?

                 Capture c = cc[j];?

                 Console.WriteLine(" Capture" + j + "=["+c.ToString()?

                   + "] Index=" + c.Index + " Length=" + c.Length);?

                 }?

                }?

              //下一個匹配?

               m = m.NextMatch();?

               }?

              這個例子的輸出如下所示:?

              Group1=[abra]?

                  Capture0=[abracad] Index=0 Length=7?

                  Capture1=[abra] Index=7 Length=4?

              Group2=[cad]?

                  Capture0=[cad] Index=4 Length=3?

              Group1=[abra]?

                  Capture0=[abracad] Index=12 Length=7?

                  Capture1=[abra] Index=19 Length=4?

              Group2=[cad]?

                  Capture0=[cad] Index=16 Length=3?

              Group1=[abra]?

                  Capture0=[abracad] Index=24 Length=7?

                  Capture1=[abra] Index=31 Length=4?

              Group2=[cad]?

                  Capture0=[cad] Index=28 Length=3?

              我們首先從考查字符串pat開始,pat中包含有表達式。第一個capture是從第一個圓括號開始的,然后表達式將匹配到一個abra。第二個capture組從第二個圓括號開始,但第一個capture組還沒有結束,這意味著第一個組匹配的結果是abracad ,而第二個組的匹配結果僅僅是cad。因此如果通過使用?符號而使cad成為一項可選的匹配,匹配的結果就可能是abra或abracad。然后,第一個組就會結束,通過指定+符號要求表達式進行多次匹配。?

              現在我們來看看匹配過程中發生的情況。首先,通過調用Regex的constructor方法建立表達式的一個實例,并在其中指定各種選項。在這個例子中,由于在表達式中有注釋,因此選用了x選項,另外還使用了一些空格。打開x選項,表達式將會忽略注釋和其中沒有轉義的空格。?

              然后,取得表達式中定義的組的編號的清單。你當然可以顯性地使用這些編號,在這里使用的是編程的方法。如果使用了命名的組,作為一種建立快速索引的途徑這種方法也十分有效。?

              接下來是完成第一次匹配。通過一個循環測試當前的匹配是否成功,接下來是從group 1開始重復對組清單執行這一操作。在這個例子中沒有使用group 0的原因是group 0是一個完全匹配的字符串,如果要通過收集全部匹配的字符串作為一個單一的字符串,就會用到group 0了。?

              我們跟蹤每個group中的CaptureCollection。通常情況下每次匹配、每個group中只能有一個capture,但本例中的Group1則有兩個capture:Capture0和Capture1。如果你僅需要Group1的ToString,就會只得到abra,當然它也會與abracad匹配。組中ToString的值就是其CaptureCollection中最后一個Capture的值,這正是我們所需要的。如果你希望整個過程在匹配abra后結束,就應該從表達式中刪除+符號,讓regex引擎知道我們只需要對表達式進行匹配。?

            基于過程和基于表達式方法的比較?
              一般情況下,使用規則表達式的用戶可以分為以下二大類:第一類用戶盡量不使用規則表達式,而是使用過程來執行一些需要重復的操作;第二類用戶則充分利用規則表達式處理引擎的功能和威力,而盡可能少地使用過程。?

              對于我們大多數用戶而言,最好的方案莫過于二者兼而用之了。我希望這篇文章能夠說明.NET語言中regexp類的作用以及它在性能和復雜性之間的優、劣點。?

            基于過程的模式?
              我們在編程中經常需要用到的一個功能是對字符串中的一部分進行匹配或其他一些對字符串處理,下面是一個對字符串中的單詞進行匹配的例子:?

              string text = "the quick red fox jumped over the lazy brown dog.";?

              System.Console.WriteLine("text=[" + text + "]");?

              string result = "";?

              string pattern = @"\w+|\W+";?

              foreach (Match m in Regex.Matches(text, pattern))?

               {?

              // 取得匹配的字符串?

               string x = m.ToString();?

              // 如果第一個字符是小寫?

               if (char.IsLower(x[0]))?

              // 變成大寫?

                x = char.ToUpper(x[0]) + x.Substring(1, x.Length-1);?

              // 收集所有的字符?

               result += x;?

               }?

              System.Console.WriteLine("result=[" + result + "]");?

              正象上面的例子所示,我們使用了C#語言中的foreach語句處理每個匹配的字符,并完成相應的處理,在這個例子中,新創建了一個result字符串。這個例子的輸出所下所示:?

              text=[the quick red fox jumped over the lazy brown dog.]?

              result=[The Quick Red Fox Jumped Over The Lazy Brown Dog.]?

            基于表達式的模式?
              完成上例中的功能的另一條途徑是通過一個MatchEvaluator,新的代碼如下所示:?

              static string CapText(Match m)?

                {?

              //取得匹配的字符串?

                string x = m.ToString();?

              // 如果第一個字符是小寫?

                if (char.IsLower(x[0]))?

              // 轉換為大寫?

                 return char.ToUpper(x[0]) + x.Substring(1, x.Length-1);?

                return x;?

                }?

                ?

               static void Main()?

                {?

                string text = "the quick red fox jumped over the?

                 lazy brown dog.";?

                System.Console.WriteLine("text=[" + text + "]");?

                string pattern = @"\w+";?

                string result = Regex.Replace(text, pattern,?

               new MatchEvaluator(Test.CapText));?

                System.Console.WriteLine("result=[" + result + "]");?

                }?

              同時需要注意的是,由于僅僅需要對單詞進行修改而無需對非單詞進行修改,這個模式顯得非常簡單。?

            常用表達式?
              為了能夠更好地理解如何在C#環境中使用規則表達式,我寫出一些對你來說可能有用的規則表達式,這些表達式在其他的環境中都被使用過,希望能夠對你有所幫助。?

            羅馬數字?
              string p1 = "^m*(d?c{0,3}|c[dm])" + "(l?x{0,3}|x[lc])(v?i{0,3}|i[vx])$";?

              string t1 = "vii";?

              Match m1 = Regex.Match(t1, p1);?

            交換前二個單詞?
              string t2 = "the quick brown fox";?

              string p2 = @"(\S+)(\s+)(\S+)";?

              Regex x2 = new Regex(p2);?

              string r2 = x2.Replace(t2, "$3$2$1", 1);?

            關健字=值?
              string t3 = "myval = 3";?

              string p3 = @"(\w+)\s*=\s*(.*)\s*$";?

              Match m3 = Regex.Match(t3, p3);?

            實現每行80個字符?
              string t4 = "********************"?

               + "******************************"?

               + "******************************";?

              string p4 = ".{80,}";?

              Match m4 = Regex.Match(t4, p4);?

            月/日/年 小時:分:秒的時間格式?
              string t5 = "01/01/01 16:10:01";?

              string p5 = @"(\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+)";?

              Match m5 = Regex.Match(t5, p5);?

            改變目錄(僅適用于Windows平臺)?
            string t6 = @"C:\Documents and Settings\user1\Desktop\";?

            string r6 = Regex.Replace(t6,@" \\user1\\ ", @" \\user2\\ ");?

            擴展16位轉義符?
              string t7 = "%41"; // capital A?

              string p7 = "%([0-9A-Fa-f][0-9A-Fa-f])";?

              string r7 = Regex.Replace(t7, p7, HexConvert);?

            刪除C語言中的注釋(有待完善)?
              string t8 = @"?

              /*?

               * 傳統風格的注釋?

               */?

              ";?

              string p8 = @"?

               /\* # 匹配注釋開始的定界符?

               .*? # 匹配注釋?

               \*/ # 匹配注釋結束定界符?

              ";?

              string r8 = Regex.Replace(t8, p8, "", "xs");?

            刪除字符串中開始和結束處的空格?
              string t9a = " leading";?

              string p9a = @"^\s+";?

              string r9a = Regex.Replace(t9a, p9a, "");?

              string t9b = "trailing ";?

              string p9b = @"\s+$";?

              string r9b = Regex.Replace(t9b, p9b, "");?

              在字符\后添加字符n,使之成為真正的新行?

              string t10 = @"\ntest\n";?

              string r10 = Regex.Replace(t10, @" \\n ", "\n");?

            轉換IP地址?
              string t11 = "55.54.53.52";?

              string p11 = "^" +?

               @"([01]?\d\d|2[0-4]\d|25[0-5])\." +?

               @"([01]?\d\d|2[0-4]\d|25[0-5])\." +?

               @"([01]?\d\d|2[0-4]\d|25[0-5])\." +?

               @"([01]?\d\d|2[0-4]\d|25[0-5])" +?

               "$";?

              Match m11 = Regex.Match(t11, p11);?

            刪除文件名包含的路徑?
              string t12 = @"c:\file.txt";?

              string p12 = @"^.*\\";?

              string r12 = Regex.Replace(t12, p12, "");?

            聯接多行字符串中的行?
              string t13 = @"this is?

              a split line";?

              string p13 = @"\s*\r?\n\s*";?

              string r13 = Regex.Replace(t13, p13, " ");?

            提取字符串中的所有數字?
              string t14 = @"?

              test 1?

              test 2.3?

              test 47?

              ";?

              string p14 = @"(\d+\.?\d*|\.\d+)";?

              MatchCollection mc14 = Regex.Matches(t14, p14);?

            找出所有的大寫字母?
              string t15 = "This IS a Test OF ALL Caps";?

              string p15 = @"(\b[^\Wa-z0-9_]+\b)";?

              MatchCollection mc15 = Regex.Matches(t15, p15);?

            找出小寫的單詞?
              string t16 = "This is A Test of lowercase";?

              string p16 = @"(\b[^\WA-Z0-9_]+\b)";?

              MatchCollection mc16 = Regex.Matches(t16, p16);?

            找出第一個字母為大寫的單詞?
              string t17 = "This is A Test of Initial Caps";?

              string p17 = @"(\b[^\Wa-z0-9_][^\WA-Z0-9_]*\b)";?

              MatchCollection mc17 = Regex.Matches(t17, p17);?

            找出簡單的HTML語言中的鏈接?
              string t18 = @"?

              <html>?

              <a href=""first.htm"">first tag text</a>?

              <a href=""next.htm"">next tag text</a>?

              </html>?

              ";?

              string p18 = @"<A[^>]*?HREF\s*=\s*[""']?" + @"([^'"" >]+?)[ '""]?>";?

              MatchCollection mc18 = Regex.Matches(t18, p18, "si");

            posted @ 2008-04-02 13:37 snowball 閱讀(239) | 評論 (0)編輯 收藏

            僅列出標題
            共2頁: 1 2 

            導航

            留言簿(1)

            隨筆分類

            友情鏈接

            搜索

            最新隨筆

            最新評論

            閱讀排行榜

            久久久亚洲欧洲日产国码aⅴ| 久久精品女人天堂AV麻| 亚洲AV日韩精品久久久久久| 少妇久久久久久被弄高潮| 99久久无码一区人妻a黑| 成人午夜精品久久久久久久小说| 日韩久久久久中文字幕人妻| 久久久无码人妻精品无码| 国产成人99久久亚洲综合精品| 色8久久人人97超碰香蕉987| 国产综合成人久久大片91| 亚洲AV日韩AV永久无码久久| 久久99国产精品成人欧美| 久久精品夜夜夜夜夜久久| 久久99精品久久久久久野外| 国产精品久久久久…| 久久久久亚洲AV成人网人人网站| 99久久婷婷国产一区二区| 国产午夜免费高清久久影院| 精品国产乱码久久久久久呢| 久久精品视频91| 国产99久久久国产精免费| 久久精品国产99国产精品澳门| 久久99热这里只频精品6| 国产精品日韩深夜福利久久| 99久久精品国产高清一区二区| 久久午夜夜伦鲁鲁片免费无码影视| 久久艹国产| 蜜桃麻豆www久久国产精品| 国产精品久久久99| 国产L精品国产亚洲区久久| 99久久亚洲综合精品网站| 伊人久久大香线蕉影院95| 久久精品国产只有精品2020| 国产精品久久99| 久久99国产精品成人欧美| 久久亚洲精品无码播放| 亚洲精品综合久久| 久久亚洲中文字幕精品有坂深雪| 久久婷婷五月综合97色| 久久青青草原精品影院|