ဒီ blog ကိုမေရးခင္ ကၽြန္ေတာ္သည္ Java beginner တစ္ေယာက္သာျဖစ္ေၾကာင္းႀကိဳတင္ေျပာထားပါရေစ။ ဒါ့ေၾကာင့္လိုအပ္တာမ်ား၊ အႀကံျပဳေဆြးေႏြးစရာမ်ားရွိပါက comment မ်ားေရးသားေဖာ္ျပနိုင္ပါတယ္။
String စာေၾကာင္းမ်ားမွရွာလိုေသာအခ်က္အလက္မ်ားကို Regular Expression ကိုသုံး၍ ရွာျခင္း
Format အတိအက်မရွိေသာ String data (စာေၾကာင္း data) မ်ားမွအခ်က္ အလက္အစိတ္ အပိုင္းမ်ား ကိုရယူရန္အတြက္ Regular Expression ကိုအသုံးျပဳနိုင္ပါတယ္။ Regular Expression ဆိုသည္မွာရွာ လိုေသာအခ်က္အလက္မ်ားကိုသင့္ေလ်ာ္ေသာ ပုံစံ (Pattern) မ်ားခ်၍ေဖာ္ျပတဲ့နည္းလမ္းျဖစ္ပါတယ္။ Java Programming တြင္ထို Regular Expression မ်ားျဖင့္ data မ်ားကိုရယူျခင္း၊ ျပဳျပင္ျခင္းမ်ားကိုျပဳလုပ္နိုင္ပါတယ္။အခုတင္ျပလိုတာကေတာ့ Java code ျဖင့္ String data မ်ားမွ ဖုန္းနံပါတ္ႏွင့္တူ ေသာ data မ်ားကိုဆြဲယူထုတ္ၾကည့္ျခင္း၊ အစားထိုးျခင္း၊ ပိုင္းျဖတ္ျခင္းစတဲ့ method မ်ားရဲ့အသုံးျပဳပုံပဲျဖစ္ပါတယ္။ ေအာက္က code ကိုၾကည့္ပါ။
1. import java.util.regex.*;
2. public class Myntel{
3. public static void main (String[] args) {
4. String msg = "I made a phone call numbered 951-123456.";
5. msg += "And I got a call numbered 9553-12345.";
6. Pattern pattern = Pattern.compile("95([0-9]{1,2}\\-[0-9]{5,6})", Pattern.CASE_INSENSITIVE);
7. Matcher match = pattern.matcher(msg);
8. while(match.find()){
9. System.out.println(match.group());
10. }
String data မွရယူလိုေသာအခ်က္အလက္ရဲ့ပုံစံကို java.util.regex package ထဲရွိ Pattern class ျဖင့္တည္ေဆာက္ နိုင္ပါတယ္။ Pattern class နဲ႔ပုံစံေတြတည္ေဆာက္တဲ့ အခါအထက္တြင္ေဖာ္ျပခဲ့တဲ့ Regular Expression ကိုအသုံးျပဳရပါတယ္။ ဒီ Regular Expression အေၾကာင္းကိုနည္းနည္းအေသးစိတ္ေျပာရမယ္ဆိုရင္ File ေတြကိုရွာေဖြရာမွာ အသုံးျပဳတဲ့ Wild Card(*) လုပ္ေဆာင္ခ်က္ကိုခ်ဲ႕ထြင္ထားတာပဲျဖစ္ပါတယ္။ Regular Expression ျဖင့္ e-mail address မ်ား URL, HTML tag စတဲ့ ရွုပ္ေထြးတဲ့စာေၾကာင္းပုံစံမ်ား ကို document မ်ားမွလြတ္လြတ္လပ္လပ္ထုတ္ယူနိုင္ပါတယ္။
အထက္မွာေဖာ္ျပခဲ့တဲ့ Java code ဟာ String စာေၾကာင္း၂ခုထဲကဖုန္းနံပါတ္မ်ား ကို Pattern class ရဲ့ object မွာျပဳလုပ္ထားတဲ့ပုံစံနဲ႔ ထုတ္ယူထားတာျဖစ္ပါတယ္။ Pattern object ကိုျပဳလုပ္ရန္အတြက္ compile method ကိုအသုံးျပဳပါတယ္။ compile method မွာ ကိုယ္ရွာခ်င္တဲ့ data ရဲ့ပုံစံကို Regular expression နဲ႔ search option ကိုေပးနိုင္ပါတယ္။ ဒီ ဥပမာမွာေတာ့ ျမန္မာနိုင္ငံရဲ့ International code ျဖစ္တဲ့ 95 နဲ႔စတဲ့နံပါတ္နဲ႔ေနာက္ကဖုန္း နံပါတ္ရဲ့ပုံစံကိုေပးထားတာပါ။ Option အေနနဲ႔ကေတာ့ CASE_INSENSITIVE field ကို ေပးထားပါတယ္။ CASE_INSENSITIVE ဟာနံပါတ္အတြက္ေတာ့မသိသာေပမယ့္အဂၤလိပ္ စာလုံးေတြကိုေတာ့အႀကီးအေသးမခြဲဘဲရွာထုတ္ေပးပါတယ္။ တျခား MULTILINE, UNICODE_CAS ဆိုတဲ့ option ေတြလည္း ရွိပါေသးတယ္။
ကိုယ္ရွာခ်င္တဲ့ပုံစံနဲ႔ Pattern object ကို တည္ေဆာက္ၿပီးၿပီဆိုလၽွင္ matcher method ျဖင့္ Matcher class ရဲ့ object ကိုတည္ေဆာက္နိုင္ပါတယ္။ Matcher object ဟာ Pattern object ျဖင့္ရွာေဖြထားတဲ့ data ေတြကို သိမ္းဆည္းထားေပးတာပါ။ အဲဒီ့ data ေတြကို find method ျဖင့္ ရွိမရွိ စစ္ေဆးၿပီး group method ျဖင့္ျပန္ေခၚထုတ္နိုင္ပါတယ္။ဒါ့ေၾကာင့္ဒီ code ကို run လိုက္ရင္ ထြက္လာမယ့္ output ကေတာ့
951-123456
9553-12345
ျဖစ္ပါတယ္။
ဒီမွာ Regular Expression မွာအသုံးျပဳတဲ့ ပုံစံ (Pattern) အခ်ိဳ႕ကိုေဖာ္ျပလိုက္ပါတယ္။
Character classes
[abc] a, b, or c (simple class)
[^abc] Any character except a, b, or c (negation)
[a-zA-Z] a through z or A through Z, inclusive (range)
[a-z&&[^bc]] a through z, except for b and c: [ad-z] (subtraction)
Greedy quantifiers
X? X, once or not at all
X* X, zero or more times
X+ X, one or more times
X{n} X, exactly n times
X{n,} X, at least n times
X{n,m} X, at least n but not more than m times
Predefined character classes
. Any character (may or may not match line terminators)
\d A digit: [0-9]
\D A non-digit: [^0-9]
\s A whitespace character: [ \t\n\x0B\f\r]
\S A non-whitespace character: [^\s]
\w A word character: [a-zA-Z_0-9]
\W A non-word character: [^\w]
Boundary matchers
^ The beginning of a line
$ The end of a line
\b A word boundary
\B A non-word boundary
\A The beginning of the input
\G The end of the previous match
\Z The end of the input but for the final terminator, if any
\z The end of the input
Ref: Java API Reference
အေပၚမွာသုံးခဲ့တဲ့ Regular Expression
95([0-9]{1,2})\\-[0-9]{5,6})
မွာ “95 နဲ႔စတဲ့နံပါတ္၁လုံးမွ၂လုံး၊ ၿပီးရင္ - နဲ႔ဆက္၊ ၿပီးရင္အေရအတြက္၅လုံးမွ၆လုံးရွိနံပါတ္” ပုံစံကို ေဖာ္ျပထားတာပါ။ ဒီ pattern ေတြကိုစတင္အသုံးျပဳရာမွာရွုပ္ေထြးမွုရွိေၾကာင္းေတြ႕ရပါ တယ္။ အခုဥပမာမွာေတာ့ရိုးရွင္းတဲ့ pattern ကိုပဲအသုံးျပဳထားပါတယ္။
Matcher နဲ႔ Pattern object ရဲ့ေနာက္ထပ္ method ၂ခုကိုေဖာ္ျပပါမယ္။ replaceAll နဲ႔ split method ပါ။
11. String result = match.replaceAll("0$1");
12. System.out.println(result);
13.
14. String log = "952 12345";
15. Pattern pattern1 = Pattern.compile("[\\s\\-]");
16. String[] result1 = pattern1.split(log);
17. System.out.println("Regional Code: " + result1[0]);
18. System.out.println("Destination No: " + result1[1]);
19. }
20.}
replaceAll method ဟာ Matcher object ထဲမွာရွိေနေသာ data မ်ားကို method ၏ parameter ျဖင့္အစားထိုးေသာ function ျဖစ္ပါတယ္။ အေပၚ code မွာ အစ နံပါတ္ 95 ကို 0 ႏွင့္အစားထိုးထားပါတယ္။ Pattern object ရွိပုံစံကိုျပန္လည္သုံးလိုပါက $ သေကၤတကိုသုံးနိုင္ပါတယ္။ $0 သည္ pattern တစ္ခုလုံးကိုရည္ညႊန္းၿပီး pattern ကို ( ) ျဖင့္ခတ္ထားပါက ေရွ႕ဆုံးမွစ၍ $1, $2 စသည္ျဖင့္ $9 အထိအသုံးျပဳနိုင္ပါတယ္။ ဒါ့ေၾကာင့္ဒီ code ကို run လိုက္ရင္ထြက္လာမယ့္ output ကေတာ့
I made a phone call numbered 01-123456.And I got a call numbered 053-12345.
ျဖစ္ပါတယ္။
split method ကေတာ့ Pattern object ရဲ့ function ျဖစ္ၿပီး Regular Expression ျဖင့္ေဖာ္ျပထားေသာပုံစံမ်ားျဖင့္ data မ်ားကိုပိုင္းျဖတ္ပါတယ္။ StringTokenizer class နဲ႔မတူတာကေတာ့ split method ဟာ return အေနနဲ႔ String array ကိုျပန္ထုတ္ ေပးတာျဖစ္ပါတယ္။ အေပၚ code မွာ 952 12345 ကို space ေနရာမွာ ပိုင္းထားၿပီး array element ျဖင့္ျပန္လည္ ေခၚထုတ္ထား ပါတယ္။ ဒီမွာ 952-12345 လို႔ေရး လည္းပိုင္းေပးမွာပါ။ split method နဲ႔ run လိုက္ရင္ထြက္လာမယ့္ output ကေတာ့
Regional Code: 952
Destination No: 12345
ျဖစ္ပါတယ္။
ဒီ Regular Expression နဲ႔ java.util.regex package ရဲ့ class နဲ႔ function မ်ား ဟာ document မ်ားမွ data မ်ားကိုရွာထုတ္ရာတြင္သာမကမိမိေရးထည့္လိုက္ေသာ data မ်ား၏ပုံစံမွန္မမွန္စစ္ေဆးရာတြင္လည္းအသုံးဝင္ပါတယ္
String စာေၾကာင္းမ်ားမွရွာလိုေသာအခ်က္အလက္မ်ားကို Regular Expression ကိုသုံး၍ ရွာျခင္း
Format အတိအက်မရွိေသာ String data (စာေၾကာင္း data) မ်ားမွအခ်က္ အလက္အစိတ္ အပိုင္းမ်ား ကိုရယူရန္အတြက္ Regular Expression ကိုအသုံးျပဳနိုင္ပါတယ္။ Regular Expression ဆိုသည္မွာရွာ လိုေသာအခ်က္အလက္မ်ားကိုသင့္ေလ်ာ္ေသာ ပုံစံ (Pattern) မ်ားခ်၍ေဖာ္ျပတဲ့နည္းလမ္းျဖစ္ပါတယ္။ Java Programming တြင္ထို Regular Expression မ်ားျဖင့္ data မ်ားကိုရယူျခင္း၊ ျပဳျပင္ျခင္းမ်ားကိုျပဳလုပ္နိုင္ပါတယ္။အခုတင္ျပလိုတာကေတာ့ Java code ျဖင့္ String data မ်ားမွ ဖုန္းနံပါတ္ႏွင့္တူ ေသာ data မ်ားကိုဆြဲယူထုတ္ၾကည့္ျခင္း၊ အစားထိုးျခင္း၊ ပိုင္းျဖတ္ျခင္းစတဲ့ method မ်ားရဲ့အသုံးျပဳပုံပဲျဖစ္ပါတယ္။ ေအာက္က code ကိုၾကည့္ပါ။
1. import java.util.regex.*;
2. public class Myntel{
3. public static void main (String[] args) {
4. String msg = "I made a phone call numbered 951-123456.";
5. msg += "And I got a call numbered 9553-12345.";
6. Pattern pattern = Pattern.compile("95([0-9]{1,2}\\-[0-9]{5,6})", Pattern.CASE_INSENSITIVE);
7. Matcher match = pattern.matcher(msg);
8. while(match.find()){
9. System.out.println(match.group());
10. }
String data မွရယူလိုေသာအခ်က္အလက္ရဲ့ပုံစံကို java.util.regex package ထဲရွိ Pattern class ျဖင့္တည္ေဆာက္ နိုင္ပါတယ္။ Pattern class နဲ႔ပုံစံေတြတည္ေဆာက္တဲ့ အခါအထက္တြင္ေဖာ္ျပခဲ့တဲ့ Regular Expression ကိုအသုံးျပဳရပါတယ္။ ဒီ Regular Expression အေၾကာင္းကိုနည္းနည္းအေသးစိတ္ေျပာရမယ္ဆိုရင္ File ေတြကိုရွာေဖြရာမွာ အသုံးျပဳတဲ့ Wild Card(*) လုပ္ေဆာင္ခ်က္ကိုခ်ဲ႕ထြင္ထားတာပဲျဖစ္ပါတယ္။ Regular Expression ျဖင့္ e-mail address မ်ား URL, HTML tag စတဲ့ ရွုပ္ေထြးတဲ့စာေၾကာင္းပုံစံမ်ား ကို document မ်ားမွလြတ္လြတ္လပ္လပ္ထုတ္ယူနိုင္ပါတယ္။
အထက္မွာေဖာ္ျပခဲ့တဲ့ Java code ဟာ String စာေၾကာင္း၂ခုထဲကဖုန္းနံပါတ္မ်ား ကို Pattern class ရဲ့ object မွာျပဳလုပ္ထားတဲ့ပုံစံနဲ႔ ထုတ္ယူထားတာျဖစ္ပါတယ္။ Pattern object ကိုျပဳလုပ္ရန္အတြက္ compile method ကိုအသုံးျပဳပါတယ္။ compile method မွာ ကိုယ္ရွာခ်င္တဲ့ data ရဲ့ပုံစံကို Regular expression နဲ႔ search option ကိုေပးနိုင္ပါတယ္။ ဒီ ဥပမာမွာေတာ့ ျမန္မာနိုင္ငံရဲ့ International code ျဖစ္တဲ့ 95 နဲ႔စတဲ့နံပါတ္နဲ႔ေနာက္ကဖုန္း နံပါတ္ရဲ့ပုံစံကိုေပးထားတာပါ။ Option အေနနဲ႔ကေတာ့ CASE_INSENSITIVE field ကို ေပးထားပါတယ္။ CASE_INSENSITIVE ဟာနံပါတ္အတြက္ေတာ့မသိသာေပမယ့္အဂၤလိပ္ စာလုံးေတြကိုေတာ့အႀကီးအေသးမခြဲဘဲရွာထုတ္ေပးပါတယ္။ တျခား MULTILINE, UNICODE_CAS ဆိုတဲ့ option ေတြလည္း ရွိပါေသးတယ္။
ကိုယ္ရွာခ်င္တဲ့ပုံစံနဲ႔ Pattern object ကို တည္ေဆာက္ၿပီးၿပီဆိုလၽွင္ matcher method ျဖင့္ Matcher class ရဲ့ object ကိုတည္ေဆာက္နိုင္ပါတယ္။ Matcher object ဟာ Pattern object ျဖင့္ရွာေဖြထားတဲ့ data ေတြကို သိမ္းဆည္းထားေပးတာပါ။ အဲဒီ့ data ေတြကို find method ျဖင့္ ရွိမရွိ စစ္ေဆးၿပီး group method ျဖင့္ျပန္ေခၚထုတ္နိုင္ပါတယ္။ဒါ့ေၾကာင့္ဒီ code ကို run လိုက္ရင္ ထြက္လာမယ့္ output ကေတာ့
951-123456
9553-12345
ျဖစ္ပါတယ္။
ဒီမွာ Regular Expression မွာအသုံးျပဳတဲ့ ပုံစံ (Pattern) အခ်ိဳ႕ကိုေဖာ္ျပလိုက္ပါတယ္။
Character classes
[abc] a, b, or c (simple class)
[^abc] Any character except a, b, or c (negation)
[a-zA-Z] a through z or A through Z, inclusive (range)
[a-z&&[^bc]] a through z, except for b and c: [ad-z] (subtraction)
Greedy quantifiers
X? X, once or not at all
X* X, zero or more times
X+ X, one or more times
X{n} X, exactly n times
X{n,} X, at least n times
X{n,m} X, at least n but not more than m times
Predefined character classes
. Any character (may or may not match line terminators)
\d A digit: [0-9]
\D A non-digit: [^0-9]
\s A whitespace character: [ \t\n\x0B\f\r]
\S A non-whitespace character: [^\s]
\w A word character: [a-zA-Z_0-9]
\W A non-word character: [^\w]
Boundary matchers
^ The beginning of a line
$ The end of a line
\b A word boundary
\B A non-word boundary
\A The beginning of the input
\G The end of the previous match
\Z The end of the input but for the final terminator, if any
\z The end of the input
Ref: Java API Reference
အေပၚမွာသုံးခဲ့တဲ့ Regular Expression
95([0-9]{1,2})\\-[0-9]{5,6})
မွာ “95 နဲ႔စတဲ့နံပါတ္၁လုံးမွ၂လုံး၊ ၿပီးရင္ - နဲ႔ဆက္၊ ၿပီးရင္အေရအတြက္၅လုံးမွ၆လုံးရွိနံပါတ္” ပုံစံကို ေဖာ္ျပထားတာပါ။ ဒီ pattern ေတြကိုစတင္အသုံးျပဳရာမွာရွုပ္ေထြးမွုရွိေၾကာင္းေတြ႕ရပါ တယ္။ အခုဥပမာမွာေတာ့ရိုးရွင္းတဲ့ pattern ကိုပဲအသုံးျပဳထားပါတယ္။
Matcher နဲ႔ Pattern object ရဲ့ေနာက္ထပ္ method ၂ခုကိုေဖာ္ျပပါမယ္။ replaceAll နဲ႔ split method ပါ။
11. String result = match.replaceAll("0$1");
12. System.out.println(result);
13.
14. String log = "952 12345";
15. Pattern pattern1 = Pattern.compile("[\\s\\-]");
16. String[] result1 = pattern1.split(log);
17. System.out.println("Regional Code: " + result1[0]);
18. System.out.println("Destination No: " + result1[1]);
19. }
20.}
replaceAll method ဟာ Matcher object ထဲမွာရွိေနေသာ data မ်ားကို method ၏ parameter ျဖင့္အစားထိုးေသာ function ျဖစ္ပါတယ္။ အေပၚ code မွာ အစ နံပါတ္ 95 ကို 0 ႏွင့္အစားထိုးထားပါတယ္။ Pattern object ရွိပုံစံကိုျပန္လည္သုံးလိုပါက $ သေကၤတကိုသုံးနိုင္ပါတယ္။ $0 သည္ pattern တစ္ခုလုံးကိုရည္ညႊန္းၿပီး pattern ကို ( ) ျဖင့္ခတ္ထားပါက ေရွ႕ဆုံးမွစ၍ $1, $2 စသည္ျဖင့္ $9 အထိအသုံးျပဳနိုင္ပါတယ္။ ဒါ့ေၾကာင့္ဒီ code ကို run လိုက္ရင္ထြက္လာမယ့္ output ကေတာ့
I made a phone call numbered 01-123456.And I got a call numbered 053-12345.
ျဖစ္ပါတယ္။
split method ကေတာ့ Pattern object ရဲ့ function ျဖစ္ၿပီး Regular Expression ျဖင့္ေဖာ္ျပထားေသာပုံစံမ်ားျဖင့္ data မ်ားကိုပိုင္းျဖတ္ပါတယ္။ StringTokenizer class နဲ႔မတူတာကေတာ့ split method ဟာ return အေနနဲ႔ String array ကိုျပန္ထုတ္ ေပးတာျဖစ္ပါတယ္။ အေပၚ code မွာ 952 12345 ကို space ေနရာမွာ ပိုင္းထားၿပီး array element ျဖင့္ျပန္လည္ ေခၚထုတ္ထား ပါတယ္။ ဒီမွာ 952-12345 လို႔ေရး လည္းပိုင္းေပးမွာပါ။ split method နဲ႔ run လိုက္ရင္ထြက္လာမယ့္ output ကေတာ့
Regional Code: 952
Destination No: 12345
ျဖစ္ပါတယ္။
ဒီ Regular Expression နဲ႔ java.util.regex package ရဲ့ class နဲ႔ function မ်ား ဟာ document မ်ားမွ data မ်ားကိုရွာထုတ္ရာတြင္သာမကမိမိေရးထည့္လိုက္ေသာ data မ်ား၏ပုံစံမွန္မမွန္စစ္ေဆးရာတြင္လည္းအသုံးဝင္ပါတယ္
0 comments:
Post a Comment