<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
捕獲組是把多個字元當一個單獨單元進行處理的方法,它通過對括號內的字元分組來建立。
例如,正規表示式 (dog) 建立了單一分組,組裡包含"d","o",和"g"。
捕獲組是通過從左至右計算其開括號來編號。例如,在表示式((A)(B(C))),有四個這樣的組:
可以通過呼叫 matcher 物件的 groupCount 方法來檢視表示式有多少個分組。groupCount 方法返回一個 int 值,表示matcher物件當前有多個捕獲組。
在Java正規表示式的相關類Matcher中,有如下幾個方法:
- int groupCount() - String group(int group) - int start(int group) - int end(int group) - String group(String name) - int start(String name) - int end(String name)
String text = "John writes about this, and John Doe writes about that," + " and John Wayne writes about everything."; String patternString = "(John) (.+?) "; Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(text); matcher.find();//匹配字串,匹配到的字串可以在任何位置 int start = matcher.start();//返回當前匹配到的字串在原目標字串中的位置 int end = matcher.end();//返回當前匹配的字串的最後一個字元在原目標字串中的索引位置 System.out.println("found group: group(0) is '" + matcher.group(0)); System.out.println("found group: group(1) is '" + matcher.group(1) + "',group(2) is '" + matcher.group(2)+"'"); patternString= "(?:John)"; Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(text); System.out.println("groupCount is -->" + matcher.groupCount()); while (matcher.find()) { System.out.println("found: " + matcher.group(1)); }
執行結果:
found group: group(0) is ‘John writes
found group: group(1) is ‘John’,group(2) is ‘writes’
groupCount is –>0
Exception in thread “main” java.lang.IndexOutOfBoundsException: No group 1
從輸出結果可以看出,當正規表示式包含多個group時,也就是含有多個’(pattern)’格式的子表示式時,它的分組索引(group number)是從1開始的,而group(0)代表了整個匹配的字串.
總結:
(1)正規表示式中以'()'標記的子表示式所匹配的內容就是一個分組(group),分組索引是從1開始的,0代表正規表示式匹配的整個字串,group(i)代表第i組匹配的內容。
(2)groupCount() 函數返回當前正規表示式中分組的個數。
(3)類似於(?:pattern)格式的子表示式不能算是一個分組。
String text = "John writes about this, and John Doe writes about that," + " and John Wayne writes about everything."; String patternString = "(John) (.+?) "; Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(text); matcher.find();//匹配字串,匹配到的字串可以在任何位置 int start = matcher.start();//返回當前匹配到的字串在原目標字串中的位置 System.out.println(start);//0 int end = matcher.end();//返回當前匹配的字串的最後一個字元在原目標字串中的索引位置 System.out.println(end);//12 start = matcher.start(1);//第一個分組匹配的內容,也就是John開始的索引位置,0 System.out.println(start);//0 start = matcher.start(2);//第一個分組匹配的內容,也就是writes開始的索引位置,5 System.out.println(start);//5 end = matcher.end(1);//第一個分組匹配的內容,也就是John結束的索引位置,4 System.out.println(end);//4 end = matcher.end(2);//第二個分組匹配的內容,也就是writes開始的索引位置,12 System.out.println(end);//12 start = matcher.start(3);//Exception in thread "main" java.lang.IndexOutOfBoundsException: No group 3
總結:
(1)當索引大於正規表示式中實際存在的索引數量,也就是groupCount()返回值時會丟擲異常。
(2)int start(int group) 返回當前分組匹配到的字串在原目標字串中的位置。
(3)返回當前分組匹配的字串的最後一個字元在原目標字串中的索引位置。
1.1 java 替換 ${xxx} 的內容
private static String parse(String content,Map<String,String> kvs){ Matcher m = p.matcher(content); StringBuffer sr = new StringBuffer(); while(m.find()){ String group = m.group(); m.appendReplacement(sr, kvs.get(group)); } m.appendTail(sr); return sr.toString(); } public static void main(String[] args) { Map<String,String> m=new HashMap<>(); m.put("${a}","han"); m.put("${b}","zhong"); System.out.println( parse("例如有這樣一個${a}字串字串:使用者'${a}'的名稱${b}", m)); }
1.2 java正規表示式appendReplacement和appendTail方法
appendReplacement是java中替換相應字串的一個方法
appendReplacement(StringBuffer sb,String replacement)
將當前匹配子串替換為指定字串,並且將替換後的子串以及其之前到上次匹配子串之後的字串段新增到一個 StringBuffer 物件裡
appendTail(StringBuffer sb)
將最後一次匹配工作後剩餘的字串新增到一個 StringBuffer 物件裡
如果沒有理解的話,那就來一個簡單的demo吧
public class TheReplacements { public static void main(String[] args) throws Exception { // 生成 Pattern 物件並且編譯一個簡單的正規表示式"cat" Pattern p = Pattern.compile("cat"); // 用 Pattern 類的 matcher() 方法生成一個 Matcher 物件 Matcher m = p.matcher("fatcatfatcatfat"); StringBuffer sb = new StringBuffer(); while(m.find()){ //此時sb為fatdogfatdog,cat被替換為dog,並且將最後匹配到之前的子串都新增到sb物件中 m.appendReplacement(sb,"dog"); } //此時sb為fatdogfatdogfat,將最後匹配到後面的子串新增到sb物件中 m.appendTail(sb); //輸出內容為fatdogfatdogfat System.out.println("sb:"+sb); } }
1.3 正規表示式matcher.group()用法
package cn.oldlu.regexp.singlecharacter; import java.util.regex.Matcher; import java.util.regex.Pattern; public class GroupIndexAndStartEndIndexTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub String str = "Hello,World! in Java."; Pattern pattern = Pattern.compile("W(or)(ld!)"); Matcher matcher = pattern.matcher(str); while(matcher.find()){ System.out.println("Group 0:"+matcher.group(0));//得到第0組——整個匹配 System.out.println("Group 1:"+matcher.group(1));//得到第一組匹配——與(or)匹配的 System.out.println("Group 2:"+matcher.group(2));//得到第二組匹配——與(ld!)匹配的,組也就是子表示式 System.out.println("Start 0:"+matcher.start(0)+" End 0:"+matcher.end(0));//總匹配的索引 System.out.println("Start 1:"+matcher.start(1)+" End 1:"+matcher.end(1));//第一組匹配的索引 System.out.println("Start 2:"+matcher.start(2)+" End 2:"+matcher.end(2));//第二組匹配的索引 System.out.println(str.substring(matcher.start(0),matcher.end(1)));//從總匹配開始索引到第1組匹配的結束索引之間子串——Wor } } }
執行結果:
Group 0:World!
Group 1:or
Group 2:ld!
Start 0:6 End 0:12
Start 1:7 End 1:9
Start 2:9 End 2:12
Wor
身份證號碼驗證
1、號碼的結構 公民身份號碼是特徵組合碼,由十七位數位本體碼和一位校驗碼組成。排列順序從左至右依次為:六位數位地址碼,八位數位出生日期碼,三位數位順序碼和一位數位校驗碼
2、地址碼(前六位數)表示編碼物件常住戶口所在縣(市、旗、區)的行政區劃程式碼,按GB/T2260的規定執行
3、出生日期碼(第七位至十四位)表示編碼物件出生的年、月、日,按GB/T7408的規定執行,年、月、日程式碼之間不用分隔符
4、順序碼(第十五位至十七位)表示在同一地址碼所標識的區域範圍內,對同年、同月、同日出生的人編定的順序號, 順序碼的奇數分配給男性,偶數分配給女性
5、校驗碼(第十八位數)
(1)十七位數位本體碼加權求和公式 S = Sum(iDCardNo * wf), i = 0, … , 16 ,先對前17位數位的權求和 iDCardNo:表示第i位置上的身份證號碼數位值 Wi:表示第i位置上的加權因子 wf: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
(2)計算模 Y = mod(S, 11) (3)通過模得到對應的校驗碼 Y: 0 1 2 3 4 5 6 7 8 9 10 校驗碼: 1 0 X 9 8 7 6 5 4 3 2
import org.junit.Test; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Hashtable; import java.util.regex.Matcher; import java.util.regex.Pattern; public class JunitIDCardTest { @Test public void test(){ System.out.println(IdentityCardVerification("110101199003074370")); } /** *身份證驗證 * @param idStr * @return */ public static String IdentityCardVerification(String idStr){ String[] wf = { "1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2" }; String[] checkCode = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2" }; String iDCardNo = ""; try { //判斷號碼的長度 15位或18位元 if (idStr.length() != 15 && idStr.length() != 18) { return "身份證號碼長度應該為15位或18位元"; } if (idStr.length() == 18) { iDCardNo = idStr.substring(0, 17); } else if (idStr.length() == 15) { iDCardNo = idStr.substring(0, 6) + "19" + idStr.substring(6, 15); } if (isStrNum(iDCardNo) == false) { return "身份證15位號碼都應為數位;18位元號碼除最後一位外,都應為數位"; } //判斷出生年月 String strYear = iDCardNo.substring(6, 10);// 年份 String strMonth = iDCardNo.substring(10, 12);// 月份 String strDay = iDCardNo.substring(12, 14);// 月份 if (isStrDate(strYear + "-" + strMonth + "-" + strDay) == false) { return "身份證生日無效"; } GregorianCalendar gc = new GregorianCalendar(); SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd"); if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150 || (gc.getTime().getTime() - s.parse(strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) { return "身份證生日不在有效範圍"; } if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) { return "身份證月份無效"; } if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) { return "身份證日期無效"; } //判斷地區碼 Hashtable h = GetAreaCode(); if (h.get(iDCardNo.substring(0, 2)) == null) { return "身份證地區編碼錯誤"; } //判斷最後一位 int theLastOne = 0; for (int i = 0; i < 17; i++) { theLastOne = theLastOne + Integer.parseInt(String.valueOf(iDCardNo.charAt(i))) * Integer.parseInt(checkCode[i]); } int modValue = theLastOne % 11; String strVerifyCode = wf[modValue]; iDCardNo = iDCardNo + strVerifyCode; if (idStr.length() == 18 &&!iDCardNo.equals(idStr)) { return "身份證無效,不是合法的身份證號碼"; } }catch (Exception e){ e.printStackTrace(); } return ""; } /** * 地區程式碼 * @return Hashtable */ private static Hashtable GetAreaCode() { Hashtable hashtable = new Hashtable(); hashtable.put("11", "北京"); hashtable.put("12", "天津"); hashtable.put("13", "河北"); hashtable.put("14", "山西"); hashtable.put("15", "內蒙古"); hashtable.put("21", "遼寧"); hashtable.put("22", "吉林"); hashtable.put("23", "黑龍江"); hashtable.put("31", "上海"); hashtable.put("32", "江蘇"); hashtable.put("33", "浙江"); hashtable.put("34", "安徽"); hashtable.put("35", "福建"); hashtable.put("36", "江西"); hashtable.put("37", "山東"); hashtable.put("41", "河南"); hashtable.put("42", "湖北"); hashtable.put("43", "湖南"); hashtable.put("44", "廣東"); hashtable.put("45", "廣西"); hashtable.put("46", "海南"); hashtable.put("50", "重慶"); hashtable.put("51", "四川"); hashtable.put("52", "貴州"); hashtable.put("53", "雲南"); hashtable.put("54", "西藏"); hashtable.put("61", "陝西"); hashtable.put("62", "甘肅"); hashtable.put("63", "青海"); hashtable.put("64", "寧夏"); hashtable.put("65", "新疆"); hashtable.put("71", "臺灣"); hashtable.put("81", "香港"); hashtable.put("82", "澳門"); hashtable.put("91", "國外"); return hashtable; } /** * 判斷字串是否為數位 * @param str * @return */ private static boolean isStrNum(String str) { Pattern pattern = Pattern.compile("[0-9]*"); Matcher isNum = pattern.matcher(str); if (isNum.matches()) { return true; } else { return false; } } /** * 判斷字串是否為日期格式 * @param strDate * @return */ public static boolean isStrDate(String strDate) { Pattern pattern = Pattern.compile("^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s(((0?[0-9])|([1-2][0-3]))\:([0-5]?[0-9])((\s)|(\:([0-5]?[0-9])))))?$"); Matcher m = pattern.matcher(strDate); if (m.matches()) { return true; } else { return false; } } }
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45