SSISO Community

시소당

자바 Regex API는 설명했다

2005년  2월  1일

독자  등급:  8.9

오는  장시간이었다,  그러나  java.util.regex  포장은  자바  1.4에  뜻깊고  거대하게  유용한  추가이었다.  일정하게  원본에  근거한  내용을  취급하는  웹  개발자를  위해,  이것은  중요한  생산력과  효율성  후원을  대표한다.  자바  정규식은  클라이언트  측  Java  애플릿과  또한  서버  측  J2EE와  JSP  부호에서  사용될  수  있다.

정규식  및  regex  포장을  사용하여,  당신은  쉽게  기술하고,  원본의  복잡한  본을  찾아내고  교묘히  다룰  수  있다.  나가  그것  없이  이제까지?"  곁에  얻은  방법  저를  의  이것  이다  명확하게  "신뢰하십시오  것의  종류.

나가  정규식의  뒤에  일반  아이디어를  설명할  이  기사에서  java.util.regex  포장이  어떻게  작동하는지,  설명하고십시오,  그  후에  얼핏  봄으로  정규식을  이용하기  위하여  끈  종류가  어떻게에  개조된지  위로  감싸십시오.

우리가  자바  regex  API  자체의  세부사항으로  들어가기  전에,  무역에서  그들에  얼마나  정규식,  또는,  "regex"가  있자,  실제로  인에  얼핏  봄이.  정규식이인  무슨  당신이  이미  알고  있는  경우에,  이  다음  섹션에  대충  훑어  보게  자유롭게  느끼십시오.
정규식은  무엇인가?

정규식은  당신이  본을  사용하여  원본에  있는  부분  문자열을  기술하는  것을  허용하는  오자  및  일련의  메타  문자이다.  이  메타  문자는  실제로  소형  언어를  형성한다.  실제로,  많은  방법으로,  당신은  자유로운  흐르는  원본을  위한  SQL  질문의  종류로  정규식을  생각할  수  있다.  뒤에  오는  문장을  고려하십시오:

나의  이름은  이고  나는  williamstown에서  산다.

우리는  어떻게",  에  관계  없이  위  원본의  모든  발생을  "찾아낼  수  있었는가  또는  소문자  "w"  사용되었다?  정규식으로  당신은  일련의  메타  문자  및  오자에게서  한  본을  구성해서  이  필요조건을  기술할  수  있다.  그런  본은  여기에서  있다:

  

[Ww]  악

이  자기의  매우  똑바른.  재미있는  부분은  [Ww]  분류이다  --  부류  안에서  둘러싸인  편지의  아무  것나  (이  경우에는,  대문자  "W"  또는  소문자  "w")  수락가능하다는  것을  나타낸다.  이렇게,  대문자  소문자  w로  시작되는  원본이  이  정규식에  의하여  일치하고,  오자에  I,  그  후에  l,  그리고  그  후에  다른  l.  선행된다.

노치  높은  쪽으로  족답하자  그것.  의지의  2개의  발생이  상기  정규식에  의하여  실제로  일치할  것이다  --  이름은  williamstown에  있는  원본의  첫번째  4개의  문자  의도한다.  우리는  의지와  의지  서만  그리고  간단하게  이  4개의  특성을  차례로  포함하는  낱말을  아닙니다  찾고  싶었다  있을지도  모른다.  개량한  버전은  여기에서  있다:

\  b  [Ww]  악  \  b

\  b  우리가  워드  경계를  기술하는  방법  이다.  선의  공간,  탭  및  처음과  끝  점의  좋아하는  것이  워드  경계에  의하여  일치할  것이다.  이것은  성냥으로  효과적으로  williamtown에  있는  두번째  l가  워드  경계에  선행되지  않기  때문에  williamstown를  제외한다  --  그것은  i.에  의해  따랐다.

나는  만드는  정규식의  순수  예술에  전체  기사를  바칠  수  있었다,  그러나  여기에서  나의  초점은  자바  정규식  포장  자체에  있다.  이렇게,  1개의  정규식을  시험하자  --  우리는  기사의  나머지를  통하여  이  것으로  찌를  것이다.

  (\  w+)  @  (\  w+  \.)(\  w+)  (\.  \  w+)?

이  본  분석  분할하  그리고  정복  접근을  채택하자.  (\  w+)  분류  (두번  나타난다  --  것을  처음에는)  찾는다  \  w.에  의해  표시되는  것과  같이  낱말  특성을  시험하십시오.  한개  이상  낱말  특성이  나타나야  한ㄴ다는  것을  +  나타낸다  (필요하지  않게  동일한  것).  이것은  문자  @  특성에  선행되어야  한다.  괄호는  실제로  여기에서  요구되지  않는다,  그러나  배치로  표정을  분할하고,  저것  논리적인  배치를  형성하는  것이  이와같이  극단적으로  유용할  다는  것을  당신은  곧  볼  것이다.

우리의  보기  regex의  이  첫번째  부분에  기초를  두어,  (\  w+)  @  부분은,  여기에서  요구에  이제까지는  응하는  약간  보기이다:

  billy@
  joe@
  francisfordcoppola@

다음  부분으로  따라  움직이자.  (\  w+  \.)  분류는  유사하,  그러나  성냥을  만들기  위하여  따르도록  기간을  기대한다.  기간은  백슬래시를  사용하여  기간  특성  자체가  regex  메타  문자  (어떤  특성든지  일치하는)  자유패이기  때문에  도주되었다.  당신은  당신이  그들의  문자  의미에  어울리고  싶은  경우에  항상  메타  문자를  이와같이  도주해야  한다.
요구에  이제까지는  응할  약간  보기를  보자:

  billy@webworld.
  joe@optus.
  francisfordcoppola@myisp.

(\  w+)  분류는  첫번째  분류와  동일하다  --  그것은  한개  이상  낱말  특성을  찾는다.  당신이  이미  깨달아  확신한  대로  이렇게,  우리의  정규식은  이메일  주소와  일치하기  위하여  예정된다.

요구에  이제까지는  응하는  약간  보기:

  billy@webworld.com
  joe@optus.net
  francisfordcoppola@myisp.com

우리는  거의  거기  있다.  (\.  \  w+)  *  분류는  주로  이  때  이해되어야  한다  --  우리는  한개  이상  낱말  특성에  선행된  기간을  찾고  있다.  그러나  *  closing  괄호  후에  -로  무엇이인가?  정규식의  세계에서는,  우리는  *  선행하는  메타  문자,  오자  또는  그룹이  시간  더  0  또는  생길  다는  것을  표시하는  것을  사용한다.  0  또는  손가락  더에  선행된  낱말  특성이  한  예로,  에  의하여  \  w  \  d*  일치할  것입니다.  우리의  보기에서는,  우리는  일련의  메타  문자를  함께  분류하기  위하여  괄호를,  그래서  이용한다  *  전체  그룹에게  적용한다.  이렇게,  당신은  해석할  수  있다  (\.  *  "한개  이상  낱말  특성을  거쳐  따른  기간  성냥으로  -  \  w+),  그리고  성냥  조합  0  이상  시간".

완전한  정규식의  요구에  응하는  약간  보기:

  fred@vianet.com
  barney@comcorp.net.au
  wilma@mjinteractive.iinet.net.au

우리의  정규식이  만들어진  상태에서,  그것은  것의  자바  측으로  위에  움직이는  시간  이다.  당신이  알  필요가  있을  맨처음  것은  자바  끈과  정규식  사이  오히려  불운한  통어론  충돌을  싸우는  방법  이다.  당신이  의  개발자,  취급해야  하는  충돌이다.
자바  안전한  정규식

경미하게  성가시다,  그러나  당신의  정규식을  자바  부호에  있는  사용을  위해  안전할  시키기  위하여  당신이  필요로  할  사실  유물이다.  이것은  어떤  백슬래시에  의하여  한계를  정한  메타  문자든지  도주될  필요가  있을  것이라는  점을  의미한다.  이것은  백슬래시  특성에는  자바에  있는  그것의  자신의  특별한  의미가  있기  때문이다.  이렇게,  우리의  보기  이메일  주소  regex는  다음과  같이  다시  쓰여야  할  것입니다:

  끈  emailRegEx  =  "(\  \  w+)  @  (\  \  w+  \  \.)(\  \.  \  \  w+)  (\  \  w+)  *";

당신이  실제로  문자  백슬래시에  대하여  어울릴  필요가  있는  경우에,  당신은  위로  그러나  다시  두배로  해야  한ㄴ다는  것을  명심하십시오.  자바  안전한  regex를  읽는  것은  곤란할  수  있다,  그래서  당신은  "일정한"  정규식  (아마  regregex?)를  만들고  첫째로  싶을  수도  있다  그리고  사본을  경편한  유지하십시오  --  아마  부호  코멘트  안쪽에.

이렇게,  우리는  어떻게  모든  유용한  무언가를  달성하는  이것을  사용하는가?  특정  상황에서는,  당신은  ()  끈  종류에  replaceAll  ()  직접적으로  간단하게  방법을과  같은  대체한다  부르골  --  우리는  이  접근에  얼핏  봄을  나중에  가지고  갈  것이다.  그러나,  더  정교한  regex  operatations를  위해,  객체  지향  접근을  채택해서  도움이  되어  당신은  멀리  더  나을  것이  일  것이다.
본  종류

상쾌하게  하는  무언가는  여기에서  있다:  java.util.regex  포장은  단지  3개의  종류만  포함한다  --  그리고  그것들중  하나는  예외이다!  당신이  예상하기  때문에,  쉽  에  배우  API를  위해  아주  만든다  이.  regex  포장을  이용하기  위하여  당신이  일반적으로  따를  것입니다  3개  단계는  여기에서  있다:

      1.  본  종류를  사용하여  당신의  regex  끈을  집계하십시오.
      2.  확인  회로  목표를  얻기  위하여  본  종류를  이용하십시오.
      3.  어떤  성냥든지에  얻기  위하여  확인  회로에  방법을  부르십시오.  

우리는  확인  회로  종류를  다음  보고,  그러나  보기로  본  종류에  안으로  급강하하자.  이  종류는  당신이  당신의  정규식을  집계하게  한다  --  이것은  다수  표적  끈  (에  의하여  효과적으로  효율성과  사용을  위해  그것을  당신이  집계한  정규식을  시험하고  싶은)  끈  낙관한다.  뒤에  오는  보기를  고려하십시오:

          emailRegEx를  =  "(\  \  w+)  @  묶으십시오  (\  \  w+  \  \.)(\  \.  \  \  w+)  (\  \  w+)  *";
          //는  본  목표에  참고를  집계하고  얻는다.
          본  본  =  Pattern.com  더미  (emailRegEx);
          //는  확인  회로  목표를  얻는다  -  우리는  이  다음을  덮는다.
          확인  회로  확인  회로  =  pattern.matcher  (emailRegEx);

본  목표가  본  종류의  공전을  통해  만회되었다  포획  주는  방법을  집계한다  --  당신은  새로운을  사용하여  instantiate  본  목표  할  수  있지  않는다.  일단  당신은  본  목표가  있으면  당신은  확인  회로  목표에  참고를  얻기  위하여  그것을  이용할  수  있다.  우리는  확인  회로를  다음  본다.
확인  회로  종류

먼저,  나는  정규식이  자유로운  흐르는  원본을  위한  SQL  질문의  종류다는  것을  건의했다.  유례는  전체로  완전하지  않다,  그러나  때  regex  API를  사용하고다  이  선에  따라서  생각할  것을  도울  수  있을.  당신이  Pattern.com  더미  (myRegEx)를  JDBC  PreparedStatement의  종류인  것으로  생각하는  경우에,  당신은  본  종류  확인  회로  (targetString)  방법을  SQL  추려낸  계산서의  종류  생각할  수  있다.  뒤에  오는  부호를  공부하십시오:

      //는  regex를  집계한다.
      끈  regex  =  "(\  \  w+)  @  (\  \  w+  \  \.)(\  \.  \  \  w+)  (\  \  w+)  *";
      본  본  =  Pattern.com  더미  (regex);
      //는  우리가  질문하는  것을  바라는  "표적"  끈을  창조한다.
      targetString  끈  =  "당신은  g_andy@example.com  또는  andy@example.net에  정보  더"를  얻기  위하여  저를  이메일을  보낼  수  있다;
      //는  확인  회로를  표적  끈에  근거하  얻는다.
      확인  회로  확인  회로  =  pattern.matcher  (targetString);

      //  발견  모든  성냥.
      동안에  (matcher.find  ())  {
          System.out.println  ("성냥을  찾아냈다:  "  +  matcher.group  ());
          System.out.println  ("출발  장소:  "  +  matcher.start  ());
          System.out.println  ("끝  위치:  "  +  matcher.end  ());
      }

여기에서  계속하는  약간  재미있는  것이  있다.  확인  회로  목표를  얻기  위하여  우리가  본  종류의  확인  회로  ()  방법을  이용했다는  것을  첫째로  위로,  주의하십시오.  우리의  SQL  유례를  사용하여  이  목표는,  아직도,  유래  성냥이  붙드는  곳  이다  --  JDBC  ResultSet를  생각하십시오.  기록은,  당연히,  우리의  정규식과  일치한  원본의  부분이다.

조건적으로  확인  회로  종류의  발견  ()  방법의  결과에  근거하는  동안  루프  뛰기.  이  방법  분석하  충족될  만큼  의  우리  표적  끈  만들  성냥,  어떤  순간에  그것  돌려보내  진실하.  조심하십시오:  런타임에  던져지는  발견을  부르기  전에  확인  회로를  이용하는  어떤  시도든지  검사받지  않는  IllegalStateException  ()  귀착될  것이다.

우리의  동안  루프의  몸에서  우리는  확인  회로  종류의  그룹  ()  방법을  사용하여  일치한  부분  문자열을  만회했다.  우리의  동안  루프는  두번  수행한다:  한  번  우리의  표적  끈에  있는  각  이메일  주소를  위해.  매번,  그것은  그룹  ()  방법으로  돌려보내진  일치한  이메일  주소,  및  부분  문자열  위치  정보를  인쇄한다.  산출을  보십시오:

성냥을  찾아냈다:  g_andy@example.com
출발  장소:  20
끝  위치:  38
성냥을  찾아냈다:  andy@example.net
출발  장소:  42
끝  위치:  58

당신이  볼  수  있던  대로,  간단하게  확인  회로의  시작  ()  및  끝  ()  방법  일치한  부분  문자열이  표적  끈에서  어디  생기는지  알아내는  이용의  사정  이었다.  다음  위로,  그룹  ()  방법에  면밀한  관찰.
이해  그룹

학구  당신으로,  Matcher.group는  표적  끈에서  ()  완전한  성냥을  만회할  것이다.  그러나  만약에  당신이  또한  일치한  원본의  일부,  또는  "소집단"에  관심  있으면  무엇?  우리의  전자  우편  보기에서는,  이메일  주소  및  사용자  이름  부분의  호스트  이름  부분을  추출하는  것이  바람직할지도  모른다.  루프  동안에  몬  우리의  확인  회로의  개정  버전  보십시오:

      동안에  (matcher.find  ())  {
          System.out.println  ("성냥을  찾아냈다:  "  +  matcher.group  (0)  +
                                                ".  사용자  이름은"  +  이다
                                                matcher.group  (1)  +  "와  ISP는"  +  이다
                                                matcher.group  (2));
      }

당신이  되부를지도  모르다  대로,  그룹은  당신의  본의  일부의  주위에  감싸인  괄호의  세트로  대표된다.  보기,  더  특정한  Matcher.group  (0)에서  것과  같이  Matcher.group를  사용하여  ()  또는,  있는  첫번째  그룹은,  전체  성냥을  대표한다.  더  그룹은  동일한  그룹  (int  색인)  방법을  사용하여  찾아낼  수  있다.  위  보기를  위한  산출은  여기에서  있다:

성냥을  찾아냈다:  g_andy@example.com.  사용자  이름은  g_andy  이고  ISP는  보기이다.
성냥을  찾아냈다:  andy@example.net.  사용자  이름은  andy  이고  ISP는  보기이다.

당신이  볼  수  있던  대로,  그룹  (1)는  이메일  주소  및  그룹  (2)의  사용자  이름  부분을  만회한다  ISP  부분을  만회한다.  당신의  자신의  정규식을  만들  때  그것은  당신까지,  당연히,  어떻게  당신  논리적으로  소집단  당신의  본  이다.  이  예제에서  작은  감독은  기간  자체가  그룹  (2)에  의해  돌려보내진  소집단의  한  부분으로  붙잡는다  이다!

소집단이  그들의  개통  괄호의  순서에  기초를  두었다는  것을  좌에서  우로  색인이  붙는는다는  것을  명심하십시오.  이것은  당신이  다른  그룹  안에  보금자리가  되는  그룹을  사용할  때  특히  중요하다.
본과  확인  회로  종류에  조금  더  많은  것

저것은  거의  이  아주  작고의  중핵,  그러나  아주  가능한,  자바  API이다.  그러나,  일단  당신은  기초로  실험하는  기회가  있으면  당신이로  봐야  하는  다른  약간  다양한  것들이  있다.  본  종류에는  당신이  그것에  두번째  논쟁으로  ()  방법을  집계하는  이용할  수  있는  다수  깃발이  있다.  예를  들면,  당신은  regex  엔진을  케이스에  관계  없이  ASCII  문자와  일치하도록  말하도록  Pattern.CASE_INSENSITIVE를  이용할  수  있다.

Pattern.MULTILINE는  또  다른  유용한  것이다.  당신은  때때로  당신의  표적  끈이  부호의  일방  통행이  아니다는  것을  regex  엔진에게  말하고  싶을  것이다;  오히려,  그것은  그들의  자신의  종료  특성이  있는  몇몇  선에는  포함한다.
당신이  필요로  하는  경우에,  당신은  자바를  사용해서  다수  깃발을  결합할  수  있다  |  (수직  막대기)  통신수.  예를  들면,  당신이  multiline를  가진  regex를  집계하고  싶  무신경  지원을  싸는  경우에,  당신은  뒤에  온  것  할  수  있었다:

Pattern.com  더미  (myRegEx,  Pattern.CASE_INSENSITIVE  |  Pattern.MULTILINE);

확인  회로  종류에는  다수  재미있는  방법이,  너무  있다:  언급이  끈  replaceAll에  의하여  (replacementString  끈)와  끈  replaceFirst  (replacementString  끈)는,  특히,  여기에서  가치가  있다.

replaceAll  ()  방법은  보충  끈을  가지고  가고  그것으로  모든  성냥을  교환한다.  replaceFirst  ()  방법은  아주  유사하다  그러나  의지이다  --  당신은  그것을  짐작했다  --  성냥의  단지  첫번째  발생을  대체하십시오.  뒤에  오는  부호  보십시오:

      손가락으로  끝내는  "BBC"  낱말이  //에  의하여  일치한다.
      thePattern  끈  =  "bbc  \  \  d";
      //는  regex를  집계하고  대소문자  구별을  떨어져  전환한다.
      본  본  =  (,  Pattern.CASE_INSENSITIVE  thePattern)  Pattern.com  더미;
      //  표적  끈.
      끈  표적  =  "나는  bBC1와  BbC2를  보고  싶다  -  ITV가  너무  좋다는  것을"  나는  가정한다;
      //는  표적  끈을  위한  확인  회로를  얻는다.
      확인  회로  확인  회로  =  pattern.matcher  (표적);
      //는  BBC에  모든  참고를  밖으로  더럽힌다.
      System.out.println  (matcher.replaceAll  ("xxxx"));

Here  산출:

나는  xxxx와  xxxx를  보고  싶다  -  ITV가  역시  좋다는  것을  나는  가정한다
Backreferences

그것은  다른  중요한  regex  화제에  얼핏  봄을  가지고  가는  가치가  있다:  backreferences.  Backreferences는  regex  엔진이  수행하고  있는  동안  당신이  체포한  소집단에  접근하는  것을  허용한다.  기본적으로,  이것은  당신이  본의  뒤에  성냥의  앞  부분에서  소집단을  언급할  다는  것을  의미한다.  당신이  동일한  편지로  시작하고  끝낸  3  편지  낱말을  위해  표적  끈을  검열할  필요가  있었다고  상상하십시오  --  와우,  sos  의  미라,  것의  저  종류.  일을  할  본은  여기에서  있다:

(\  w)  (\  w)  (\  1)

이  경우에는,  (\  1)  그룹은  본에서  한  첫번째  성냥에  backreference를  포함한다.  기본적으로,  세  번째는  이  위치에서만  특성이  같은  첫번째에  있는  특성이  그룹을  parenthesised  동일하만  때  그룹을  일치할  것이다  parenthesised.  당연히,  당신은  당신이  backreference를  두번째  그룹  원한  경우에  \  1로  대용하기  위하여  \  2  간단하게  하고자  했다.  그것은  간단하다,  그러나  많은  경우에,  거창하게  유용한.

확인  회로  목표의  보충  방법  (및  끈  종류의  대조물  또한)  보충  끈에  있는  backreferences를  하기를  위한  표기법을  지원한다.  그것은  백슬래시  대신에,  그러나  용도  달러  기호  같은  방식으로  작동한다.  이렇게,  matcher.replaceAll  ("$2"  정규식의  두번째  소집단에  의해  일치한  가치로)는  표적  끈에  있는  모든  성냥을  교환할  것입니다.
끈  종류  RegEx  방법

나가  먼저  언급했다시피,  자바  끈  종류는  정규식을  이용하기  위하여  새롭게  했다.  당신은  간단한  케이스,  완전하게  끈  종류에  regex에  의하여  가능하게  된  방법을  직접적으로  불러서  regex  API를  사용하여  우회에서,  할  수  있다  직접적으로.  유효한  5개의  그런  방법이  있다.

당신은  부울  논리  연산  성냥  (끈  regex)  빨리  특정한  본이  끈에  의하여  정확하게  일치하는지  결정하기  위하여  방법을  이용할  수  있다.  string  적합하게  지명한  replaceFirst  (끈  regex,  끈  보충)와  끈  replaceAll  (끈  regex,  끈  보충)는  방법  당신이  빠르고  더러운  원본  보충을  하는  것을  허용한다.  그리고  마지막으로,  끈은  정규식에  근거한  부분  문자열로  []  (끈  regEx)  끈  []  나누었다  (끈  regEx,  int  한계)  방법을  시켰다  당신을  나누었다  끈을  나누고.  이  마지막  2개의  방법은,  java.util.StringTokenizer  의  강력한  훨씬  더와  유사한  개념에  있다.

그것이  훨씬  더  regex  API  및  객체  지향  접근을  사용하는,  많은  경우에,  이해된ㄴ다는  것을  명심하십시오.  이것을  위한  1가지의  이유는  그런  접근이  precompile  당신에게  당신의  정규식을  준다  이고  그  후에  다수  표적  끈의  맞은편에  그것을  사용한다.  또  다른  이유는  가능한  간단하게  훨씬  더이다  이다.  당신은  빨리  1개의  접근  정상을  언제의  걸림새를  선택하기  위하여  다른  사람  얻을  것이다.

희망이  있,  나는  당신에게  regex  API에서  기선을  주고  그것에게  약간  심각한  고려하기  위하여  아직  이  강력한  공구를  발견할  것인  그들을  유혹했다.  빠른  끝:  복잡한  정규식을  만드는  것을  시도하는  귀중한  개발  시간의  시간을  낭비하지  말라  --  그것은  이미  존재할지도  모른다.  그들의  전체  낱단을  자유롭게  이용할  수  있게  하는  장소의  많음이  www.regexlib.com와  같은  있다.

[출처]  자바  Regex  API  [SitePoint]|작성자  양군짱
http://blog.naver.com/yanggun7201?Redirect=Log&logNo=80033421965

642 view

4.0 stars