網(wǎng)站首頁 編程語言 正文
省流
/// <summary> /// 是否有效的文件,文件夾路徑 /// </summary> /// <param name="val"></param> /// <returns>是,返回true;不是返回false</returns> public bool IsValidFolderPath(string val) { Regex regex = new Regex(@"^([a-zA-Z]:\\)([-\u4e00-\u9fa5\w\s.()~!@#$%^&()\[\]{}+=]+\\?)*$"); Match result = regex.Match(val); return result.Success; } // "F:\\Total客戶端項目\\客戶端項目\\2017-01-09 Client\\(aa)\\V1.3.4\\New_1.2\\V13&V14\\.()~!@#$%^&()-+="; // 匹配結(jié)果:true
解釋:
分為2大段,一段匹配盤符,一段匹配后續(xù)文件、文件夾路徑
-
^([a-zA-Z]:\\):必須以盤符的形式開頭。
^表示從起始位置匹配,[a-zA-Z]表示第1位必須是a~z或A~Z其中之一。:\\表示第1位后必須接字符串:\。\\是正則中\(zhòng)的轉(zhuǎn)義。
-
([-\u4e00-\u9fa5\w\s.()~!@#$%^&()\[\]{}+=]+\\?)*$:后續(xù)以一定取值范圍組成一個個結(jié)構(gòu)。
先看[]內(nèi),\u4e00-\u9fa5表示匹配漢字,\w,\s都是元字符有其對應(yīng)的匹配范圍。其余這些字符-.()~!@#$%^&()\[\]{}+=就代表它們自身。其中\(zhòng)[是[的轉(zhuǎn)義,\]是]的轉(zhuǎn)義。[~]+表示[]中的內(nèi)容至少需要出現(xiàn)1次。\\?表示,[~]內(nèi)的字符寫完后,可以在后面接一個字符\,也可以不接。(~)*表示()內(nèi)容可以重復(fù)任意次數(shù),也可以一次不出現(xiàn)。$表示匹配到結(jié)束位置,搭配前面的^表示整個輸入字符串的結(jié)構(gòu)都得符合這個正則表達(dá)式。
幾點注意:
- 上面得[~]指代表達(dá)式中[]的所有內(nèi)容,(~)指代表達(dá)式中()的所有內(nèi)容,應(yīng)該挺好理解吧。
- 寫了解釋主要是自己總結(jié)一下,你看估計也看不懂,要不直接拿去用,要不老老實實去學(xué)吧,這些都是基礎(chǔ),就把正則表達(dá)式的基礎(chǔ)學(xué)了基本就夠用。
- 不同系統(tǒng)下可不可以匹配漢字是不一樣的。比如C#環(huán)境里\w好像就可以匹配漢字,但javascript環(huán)境里\w就匹配不了漢字。
- 正則自己的轉(zhuǎn)義和放入字符串中的轉(zhuǎn)義挺容易懵的,寫的時候要注意。
- 個人理解,只有一個路徑,是判斷不出來這個路徑是文件還是文件夾的,因為文件夾名也可以叫setup.exe,文件名也可以沒有后綴。windows的文件命名規(guī)范中只不允許9個字符的出現(xiàn)。/ \ ? * : " < > |其他都可以。
學(xué)習(xí)編寫驗證過程
鑒于網(wǎng)上找了好幾個都是垃圾,既不好使也不知道到底在判斷啥,所以不得不萬事靠自己。
學(xué)習(xí)自https://www.jb51.net/tools/zhengze.html
元字符metacharacter
字符 | 相關(guān)解釋 | ? |
---|---|---|
\b | 匹配單詞的開頭或結(jié)尾,也就是單詞的分界處。可用于精確查找一個單詞 | ? |
. | 匹配除了換行以外的任意字符 | ? |
* | *前面的內(nèi)容可以重復(fù)任意次 | ? |
+ | +前面的內(nèi)容可以連續(xù)重復(fù)1或任意更多次。通俗一點說,就是至少得匹配一次。 | ? |
? | ?前面的內(nèi)容可以連續(xù)重復(fù)0或1次。 | ? |
{x} | x:數(shù)字。{x}前面的內(nèi)容必須重復(fù)x次 | ? |
{x,} | x。{x,}前面的內(nèi)容必須重復(fù)至少x次 | ? |
{x,y} | x,y:數(shù)字。{x,y}前面的內(nèi)容必須重復(fù)x,y之間的次數(shù),包括x,y | ? |
(xxx) | 表示分組 | ? |
[x,y,z] | 表示單個匹配 | ? |
\d | 匹配一位十進(jìn)制數(shù)字,也就是0~9 | [0-9] |
\s | 匹配任意空白符,空格,制表符,換行符,中文全角空格等 | ? |
\w | 匹配數(shù)字,字母,下劃線【中文】 | [a-z0-9A-Z_] |
^ | 匹配字符串的開始位置 | ? |
$ | 匹配字符串的結(jié)束位置 | ? |
如何從一個字符串中查找字符串‘hi’?
Regex regex = new Regex("hi"); // 注意:如history,high等詞中的hi也會被匹配。
如何精確查找hi這個詞?使用\b
Regex regex = new Regex(@"\bhi\b");
這樣就可以精確查找到‘hi’這個詞。
如何查找hi,xxxxx,Lucy?
Regex regex = new Regex(@"\bhi\b.*\bLucy\b"); // `.*`不能換行。是匹配不包含換行的任意數(shù)量字符
如何匹配一個中國電話號碼?格式為:xx-xxxxxxxxxxxxxxx
Regex regex = new Regex(@"\d\d-\d\d\d\d\d\d\d\d\d\d\d\d\d\d\d");
如何匹配一個188開頭的電話號碼?
Regex regex = new Regex(@"\d\d-188\d\d\d\d\d\d\d\d\d\d\d\d");
這如果要匹配一個100位數(shù)字豈不是都寫不下了,所以必然存在優(yōu)化寫法。
Regex regex = new Regex(@"\d{2}-188\d{12}");
\d{2} 的話能不能匹配85555這種?與high中匹配hi一樣?
如果沒有限制也是會都匹配的,如果想要精確匹配,也要在前后使用元字符\b
如果有長號有短號想一起匹配怎么辦?
Regex regex = new Regex(@"\d{2,3}-188\d{6,12}");
解析一個電話號相關(guān)的表達(dá)式^\(?0\d{2}[) -]?\d{8}
- ^:表示驗證字符串必須以(或0開頭
- \(??:?\(是(的轉(zhuǎn)義,?表示出現(xiàn)1次或不出現(xiàn)
- 0\d{2}?: 表示0起始后面跟2位數(shù)字
- [) -]?:表示數(shù)字后面的1位或者什么都沒有,或者是),空格,-3個中的一個
- \d{8}:表示8位數(shù)字。
string phone = "(010)88886666"; string phone1 = "(010x88886666"; string phone2 = "011)-888866660000"; string phone3 = "011-888866660000"; string phone4 = "99011-88886666"; Regex regex30 = new Regex(@"^\(?0\d{2}[) -]?\d{8}"); Match resultphone = regex30.Match(phone);// 匹配成功 Match resultphone1 = regex30.Match(phone1);// 匹配失敗,因為010后出現(xiàn)了[]中不存在的字符 Match resultphone2 = regex30.Match(phone2);// 匹配失敗,因為[]后沒有接8位數(shù)字,不是說-也在[]中就可以,[]永遠(yuǎn)只匹配一個位置 Match resultphone3 = regex30.Match(phone3);// 匹配成功,因為這個正則表達(dá)式?jīng)]有用$限制結(jié)尾 Match resultphone4 = regex30.Match(phone4);// 匹配失敗,因為這個正則表達(dá)式用^限制了開頭,必須為(或0。
關(guān)于^和$
以前老不理解這玩意都啥用,其實就是對匹配范圍進(jìn)行限制。以一段數(shù)字字符為例。
正常使用9/d{2}進(jìn)行匹配,匹配條件可以解釋為,“以9開頭并在后面跟任意2位數(shù)字的字符串”可以匹配成功,也就是998。
但如果使用^進(jìn)行限制^9/d{2}。匹配條件就變?yōu)椤拜斎胱址仨毷且?并在后面跟任意2位數(shù)字開頭的字符串”。匹配就會失敗。
把9去掉^/d{2},匹配條件就變?yōu)椤拜斎胱址仨毷且匀我?位數(shù)字開頭的字符串”。匹配就會成功。
若用$限制/d{2}$,匹配條件就變?yōu)椤拜斎胱址仨毷且匀我?位數(shù)字結(jié)尾的字符串”。匹配成功。
若改為58$,匹配條件就變?yōu)椤拜斎胱址仨毷且浴?8’結(jié)尾的字符串”。匹配就會失敗。
若用^,$限制,^/d{2}$,匹配條件就變?yōu)椤拜斎胱址仨毷?位數(shù)字的字符串”,匹配失敗。
改為^/d{18}$,,匹配條件就變?yōu)椤拜斎胱址仨毷?8位數(shù)字的字符串”,匹配成功。
代碼如下:
string numberStr2 = "123456789987645312"; Regex regex2 = new Regex(@"9\d{2}"); Match result2 = regex2.Match(numberStr2); Regex regex3 = new Regex(@"^9\d{2}"); Match result3 = regex3.Match(numberStr2); Regex regex4 = new Regex(@"\d{2}$"); Match result4 = regex4.Match(numberStr2); Regex regex5 = new Regex(@"58$"); Match result5 = regex5.Match(numberStr2); Regex regex6 = new Regex(@"^\d{2}$"); Match result6 = regex6.Match(numberStr2); Regex regex7 = new Regex(@"^\d{18}$"); Match result7 = regex7.Match(numberStr2);
關(guān)于(),[],和{}
首先是{},這個沒什么說的,就是表示重復(fù)次數(shù)的。{2},{2,},{2,5}這種。
其次[]表示單個匹配。只能表示1個位置,這個位置的內(nèi)容必須為[]中的選項之一。
看到這么描述大約有以下幾種疑問
單獨使用[]有啥用?
Regex regex8 = new Regex(@"[打]"); Match result8 = regex8.Match(Str8); Regex regex9 = new Regex(@"[打s]"); Match result9 = regex9.Match(Str8); Regex regex10 = new Regex(@"[打s黑]"); Match result10 = regex10.Match(Str8); Regex regex11 = new Regex(@"[黑]"); Match result11 = regex11.Match(Str8); Regex regex12 = new Regex(@"打"); Match result12 = regex12.Match(Str8); Regex regex13 = new Regex(@"黑s打"); Match result13 = regex13.Match(Str8);// 匹配失敗 Regex regex14 = new Regex(@"[黑s打]");// 匹配成功,找到‘打' Match result14 = regex14.Match(Str8); // 單獨使用就是從頭至尾匹配輸入字符串的每一個字符。找到輸入字符串中第一個能與[]中任意一個字符匹配的上的。 // 如果[]中只有1個字符,那有沒有[]完全一樣。如果[]內(nèi)有多個字符是不一樣的。 // 想象不出來使用場景,[]在實際應(yīng)用中也大多配合其他條件一起使用
[]里要是有元字符怎么辦?
解決方法很簡單:轉(zhuǎn)義。
但具體怎么轉(zhuǎn)其實還是有點繞。這個繞不是說有多難,而是這個點你需要有印象,遇到的時候要能反映過來。
這個我認(rèn)為很容易懵的點在于C#自身字符串的轉(zhuǎn)義與正則表達(dá)式的轉(zhuǎn)義混合。
首先明確一下C#中的轉(zhuǎn)義,C#中轉(zhuǎn)義有2種方法:
// 字符原文: //a我打[]{}aa\bb"cc''dd^ee/dff //another row // '[',']','{','}',''','^','/'本身就不需要轉(zhuǎn)義,需要轉(zhuǎn)義的是'\','"',換行 // 第1種 需要轉(zhuǎn)義的符號前加'\' string stringStr1 = "a我打[]{}aa\\bb\"cc''dd^ee/dff\r\nanother row"; // 第2種,整個字符串用'@'修飾 // 這種情況下,'\',換行不用轉(zhuǎn)義了。但'"'還需要轉(zhuǎn)義,因為不轉(zhuǎn)義字符串就提前結(jié)束了,用兩個雙引號'""'表示普通字符'"' string stringStr2 = @"a我打[]{}aa\bb""cc''dd^ee/dff another row";
正則表達(dá)式中需要轉(zhuǎn)義的符號很多,所有元字符全部需要轉(zhuǎn)義。但好消息是轉(zhuǎn)義方式只有1種,就是在需要轉(zhuǎn)義的符號前加\。
這再把這些表達(dá)式放入C#字符串中,就分不清到底是字符串轉(zhuǎn)義,還是正則轉(zhuǎn)義,正則轉(zhuǎn)義后進(jìn)入字符串會不會又要轉(zhuǎn)義等等等等。懵。
元字符包括:( ) [ ] { } \ ^ $ | ? * . + /。 ”/“需不需要轉(zhuǎn)義好像有點爭議。查了一下發(fā)現(xiàn)很多編譯器關(guān)于正則的轉(zhuǎn)義是有一些默認(rèn)處理的,也沒找到個權(quán)威的規(guī)則,就視具體情況而定。
// 上面的例子,匹配一個9開頭跟2個數(shù)字的字符 Regex regex15 = new Regex("9\d{2}"); // 這樣寫就會報錯,因為正則'\d'中的'\'是c#字符串中轉(zhuǎn)義的標(biāo)識。這么寫C#就會認(rèn)為'\d'是一個轉(zhuǎn)義符,而又不知道轉(zhuǎn)義成了什么,就會報錯:CS1009:無法識別的轉(zhuǎn)義序列。 // 所需要將'\'轉(zhuǎn)義,如上使用@或另一種轉(zhuǎn)義方法都可以 Regex regex16 = new Regex(@"9\d{2}"); Regex regex17 = new Regex("9\\d{2}"); // 另一個很需要有印象的例子。就是一個位置只能使用字符'\'或字符'd' // 其實很簡單,用[]就行 Regex regex18 = new Regex("[\d]");//如上報錯:CS1009:無法識別的轉(zhuǎn)義序列。 // 一開沒轉(zhuǎn)義,改為 Regex regex19 = new Regex("[\\d]");//編譯通過,完活。 string str10 = @"a我打[]{}aa\bb""cc''dd^ee/dff\\"; Match result19 = regex19.Match(str10);// 匹配失敗 // 然而result19的結(jié)果是 匹配失敗。 // 這就是字符轉(zhuǎn)義與正則轉(zhuǎn)義的混合。 // '\\d'僅處理了字符串中'\'的問題,沒有解決正則'[\d]'中'\'也需要轉(zhuǎn)義的問題; // 想要實現(xiàn)一個位置只能使用字符'\'或字符'd',正確的正則表達(dá)應(yīng)該為[\\d] // 那么再將其放入C#字符串中,每個'\'都要再轉(zhuǎn)義一次,即為 Regex regex20 = new Regex("[\\\\d]"); Match result20 = regex20.Match(str10); // 或 Regex regex21 = new Regex(@"[\\d]"); Match result21 = regex21.Match(str10); // 我還好奇了一下[]中有重復(fù)字符會怎樣 Regex regex22 = new Regex(@"[\\\\d]"); Match result22 = regex22.Match(str10); // 結(jié)果好像沒啥區(qū)別,有相同字符無所謂的,沒影響 // 這里后續(xù)使用又發(fā)現(xiàn)了一點,補充一下 // 前文提到: Regex regex19 = new Regex("[\\d]"); string str10 = @"a我打[]{}aa\bb""cc''dd^ee/dff\\"; Match result19 = regex19.Match(str10); // 會編譯通過,但是匹配失敗。這里遺漏了一個問題,就是new Regex("[\\d]");到底再匹配什么? // 答案就是它再匹配'/d',也就是任意以為0~9的數(shù)字 string str101 = @"a我打[]{}aa\bb""cc''dd^ee/dff\\"; string str102 = @"a我打[]{}aa\bb""cc''d9d^ee/dff\\";//中間加了個9 Regex regex191 = new Regex("[\\d]"); Match result191 = regex191.Match(str101);//匹配失敗 Match result192 = regex191.Match(str102);//匹配成功,找到9 //所以[],不止能匹配[]中的實際內(nèi)容,還可以配合元字符匹配所有那一類字符
[]搭配-可以表示連續(xù)的字符
Regex regex22 = new Regex("[0-3]");// 某位置匹配0~3,也就是0,1,2,3
[]搭配^可以表示排除
Regex regex23 = new Regex("[^0-3]");// 某位置匹配除了0,1,2,3都可以。
可以復(fù)習(xí)一下要是就想匹配-,^,甚至[]怎么辦?
Regex regex24 = new Regex("[\\^\\[\\]\\-]"); //或 Regex regex25 = new Regex(@"[\^\[\]\-]");
這里實際試了一下這些特殊字符,除了[ 和 ]不轉(zhuǎn)義也能匹配,迷惑。
最后就是(),()有很多功能,包括限制多選結(jié)構(gòu)的范圍,分組,捕獲文本,環(huán)視,特殊模式處理。
我感覺比較基礎(chǔ)的使用就是限制多選與分組。
// 匹配必須整段一模一樣的abc或bcd或cde, Regex regex26 = new Regex("(abc|bcd|cde)"); // 匹配必須有連續(xù)2個adb的重復(fù),也就是abcabc,abcaabc不行 Regex regex27 = new Regex("(abc){2}");
總結(jié)
原文鏈接:https://www.cnblogs.com/whr2071/p/16084937.html
相關(guān)推薦
- 2023-07-13 el-table實現(xiàn)多選及反選
- 2022-04-01 SQL?Server的存儲過程詳解_MsSql
- 2022-05-11 如何使 React 中的 useEffect、useLayoutEffect 只調(diào)用一次
- 2022-03-11 .NET6中使用CuteEditor詳解_實用技巧
- 2022-07-28 Android?EventBus粘性事件實現(xiàn)機制探究_Android
- 2023-06-05 Python?socket之TCP通信及下載文件的實現(xiàn)_python
- 2022-11-29 C#泛型的使用案例_C#教程
- 2022-08-03 python中multiprosessing模塊的Pool類中的apply函數(shù)和apply_asyn
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支