字符串中判斷存在的幾種模式和效率(string.contains、string.IndexOf、Regex.Match),stringregex
通常情況下,我們判斷一個字符串中是否存在某值常常會用string.contains,其實判斷一個字符串中存在某值的方法有很多種,最常用的就是前述所說的string.contains,相對來說比較常用的還有string.IndexOf和Regex.Match。直接上代碼,後面在說些什麼吧,通常情況下功能的實現最重要,作者的話,只對有心者有效。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace ExistsInString { class Program { static void Main(string[] args) { string str0 = "|456|"; string str1 = "|444|"; string str2 = "|111|222|333|444|555|666|777|888|999|000|"; //------------------------------------------ //String.Contains方法 if (str2.Contains(str0)) Console.WriteLine("String.Contains->true"); else Console.WriteLine("String.Contains->false"); if (str2.Contains(str1)) Console.WriteLine("String.Contains->true"); else Console.WriteLine("String.Contains->false"); //------------------------------------------ //String.IndexOf方法 int val1 = str2.IndexOf(str0);//不存在返回-1 Console.WriteLine("String.IndexOf(no exists)->" + val1); int val2 = str2.IndexOf(str1);//存在返回str1首字符所在str2中的位置(>=0) Console.WriteLine("String.IndexOf(exists)->" + val2); //------------------------------------------ //正則匹配方法 if (Regex.Match(str2, "[|]456[|]").Success) Console.WriteLine("Regex.Match(no exists)->true"); else Console.WriteLine("Regex.Match(no exists)->false"); if (Regex.Match(str2, "[|]444[|]").Success) Console.WriteLine("Regex.Match(exists)->true"); else Console.WriteLine("Regex.Match(exists)->false"); Console.ReadKey(); /* *如果上述三種方式都處理大量數據,效率如何呢? *以下循環六組數據說明 */ int loopCount = (int)10e6; DateTime lasttime = DateTime.Now; DateTime nowtime = DateTime.Now; for (int loop = 1; loop < 7; loop++) { Console.WriteLine("\r\nloop " + loop + " >>>>>>>"); //------------------------------------------ //String.Contains方法 //no exists lasttime = DateTime.Now; for (int i = 0; i < loopCount; i++) if (str2.Contains(str0)) { }; nowtime = DateTime.Now; TimeSpan tsStrConNoExists = nowtime - lasttime; //exists lasttime = DateTime.Now; for (int i = 0; i < loopCount; i++) if (str2.Contains(str1)) { }; nowtime = DateTime.Now; TimeSpan tsStrConExists = nowtime - lasttime; //------------------------------------------ //String.IndexOf方法 //no exists lasttime = DateTime.Now; for (int i = 0; i < loopCount; i++) if (str2.IndexOf(str0) >= 0) { };//上述已經提到不存在返回-1,存在返回一個非負整數,這裏爲什麼不用 == -1 ,而是用了 >= 0 ,這是一個值得深思的問題? nowtime = DateTime.Now; TimeSpan tsStrIndNoExists = nowtime - lasttime; //exists lasttime = DateTime.Now; for (int i = 0; i < loopCount; i++) if (str2.IndexOf(str1) >= 0) { }; nowtime = DateTime.Now; TimeSpan tsStrIndExists = nowtime - lasttime; //------------------------------------------ //Regex.Match方法 //no exists Regex Reg0 = new Regex("[|]456[|]"); lasttime = DateTime.Now; for (int i = 0; i < loopCount; i++) if (Reg0.Match(str2).Success) { }; nowtime = DateTime.Now; TimeSpan tsStrRegNoExists = nowtime - lasttime; //exists Regex Reg1 = new Regex("[|]444[|]"); lasttime = DateTime.Now; for (int i = 0; i < loopCount; i++) if (Reg1.Match(str2).Success) { }; nowtime = DateTime.Now; TimeSpan tsStrRegExists = nowtime - lasttime; Console.WriteLine("no exists >>>"); Console.WriteLine("tsStrConNoExists = " + tsStrConNoExists.Milliseconds); Console.WriteLine("tsStrIndNoExists = " + tsStrIndNoExists.Milliseconds); Console.WriteLine("tsStrRegNoExists = " + tsStrRegNoExists.Milliseconds); Console.WriteLine("exists >>>"); Console.WriteLine("tsStrConExists = " + tsStrConExists.Milliseconds); Console.WriteLine("tsStrIndExists = " + tsStrIndExists.Milliseconds); Console.WriteLine("tsStrRegExists = " + tsStrRegExists.Milliseconds); } Console.ReadKey(); } } }
輸入結果:
String.Contains->false String.Contains->true String.IndexOf(no exists)->-1 String.IndexOf(exists)->12 Regex.Match(no exists)->false Regex.Match(exists)->true loop 1 >>>>>>> no exists >>> tsStrConNoExists = 796 tsStrIndNoExists = 687 tsStrRegNoExists = 171 exists >>> tsStrConExists = 484 tsStrIndExists = 234 tsStrRegExists = 796 loop 2 >>>>>>> no exists >>> tsStrConNoExists = 46 tsStrIndNoExists = 671 tsStrRegNoExists = 234 exists >>> tsStrConExists = 546 tsStrIndExists = 437 tsStrRegExists = 734 loop 3 >>>>>>> no exists >>> tsStrConNoExists = 62 tsStrIndNoExists = 875 tsStrRegNoExists = 171 exists >>> tsStrConExists = 609 tsStrIndExists = 562 tsStrRegExists = 781 loop 4 >>>>>>> no exists >>> tsStrConNoExists = 78 tsStrIndNoExists = 921 tsStrRegNoExists = 218 exists >>> tsStrConExists = 609 tsStrIndExists = 640 tsStrRegExists = 828 loop 5 >>>>>>> no exists >>> tsStrConNoExists = 156 tsStrIndNoExists = 268 tsStrRegNoExists = 265 exists >>> tsStrConExists = 609 tsStrIndExists = 578 tsStrRegExists = 890 loop 6 >>>>>>> no exists >>> tsStrConNoExists = 109 tsStrIndNoExists = 46 tsStrRegNoExists = 546 exists >>> tsStrConExists = 625 tsStrIndExists = 609 tsStrRegExists = 953
測試結果中不難發現,如果strA中不包括strB,使用strA.Contains(strB)更優;反之,如果strA中包括strB,使用strA.IndexOf(strB)更優。(Regex.Match在此方法中貌似沒有體現出任何優勢,它更適用於模糊匹配)
具體要使用string.Contains,或是string.IndexOf要看形勢。
之前有看過string下很多方法實現的代碼(微軟的,非他人),string.Contains是基於string.IndexOf上的一個方法,使用string.Contains的時候,會調用
string.IndexOf,按原理,使用string.IndexOf的效率是要高於string.Contains的,但是這個測試結果讓我大跌眼鏡,應該是我在上述代碼中使用的判斷語句造成的這種非理想的測試結果,按照個人的意願,還是希望多使用string.IndexOf。
其實一次微小的改變在當前可能影響不了什麼,但是在日積月累中,它的優勢就顯而易見了。想要快速變得比他人更強,不需要多麼費勁,只需要每天多做一點點(千分之一)
一年之後:(1 + 0.001)365 = 1.44倍
十年之後(1 + 0.001)3650 = 38.4倍
這是一種優勢的計算,這是一種能力的計算,這是一種薪水的計算,...,不管是什麼的計算,請記得每天只需進步一點點,隨着時間的積累,你將會蛻變。該吃吃,該喝喝,該玩玩,該睡睡...只需要將你每天白日夢囈和漫無目的做無意義事情的時間用到它該用到的地方,你就在進步。
有大小寫字母的字符串與一個查找字符,使用類String方法indexOf()來判斷在該字符串中該字符出現的次數
public class TestIndexOf { public static void main(String[] args) { int i=(new TestIndexOf()).f(); System.out.println(i); } int f() { char c='H'; String str="dhdisHIHkdsjfHiodfHHlkIFH"; int i=str.indexOf(c); //System.out.println(i);調試用 if(i==-1) { return 0; } int count=1; while(true) { i=str.indexOf(c,i+1); if(i!=-1) { count++; } else break; } return count; } }
String contains indexOf不同 contains是找指定字符串是否包含一個字串,返回值的boolean類型,即只有true和false
indexOf有多個重載,但無論哪個,都是做一定的匹配,然後把匹配的第一個字符的位置返回,返回的是int類型,如果沒找到,那麼返回-1