public:computer:regexp

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revisionBoth sides next revision
public:computer:regexp [2021/08/23 20:52] alexpublic:computer:regexp [2023/01/01 00:56] – [참조 그룹] alex
Line 1: Line 1:
 ====== Regular Expressions ====== ====== Regular Expressions ======
-<lead>정규표현식은 특정 문자열을 가리키는 패턴이다. 즉 이 패턴으로 원하는 문자열을 찾는다.</lead> - 켄 톰슨+**정규표현식은 특정 문자열을 가리키는 패턴이다. 즉 이 패턴으로 원하는 문자열을 찾는다.** - 켄 톰슨
  
 ===== 기본 패턴 찾기 ===== ===== 기본 패턴 찾기 =====
Line 9: Line 9:
   * 수량자; {숫자}: 해당 갯수, {최소숫자,최대숫자}: 최소숫자부터 최대숫자 갯수만큼 , ?: 하나 이하, +: 하나 이상, *: 0 이상   * 수량자; {숫자}: 해당 갯수, {최소숫자,최대숫자}: 최소숫자부터 최대숫자 갯수만큼 , ?: 하나 이하, +: 하나 이상, *: 0 이상
   * 상수   * 상수
 +
 +^  정규표현식의 메타 문자  ^^^^
 +^ 메타 문자  ^ 이름  ^ 코드 포인트  ^ 의미  ^
 +^ .  | 점  | U+002E  | 임의의 문자를 찾음  |
 +^ \  | 역슬래시  | U+005C  | 문자의 특수 의미를 없앰  |
 +^ %%|%%  | 세로줄  | U+007C  | 선택  |
 +^ %%^%%  | 악센트 기호  | U+005E  | 행의 시작을 나타내는 앵커  |
 +^ $  | 달러 기호  | U+0024  | 행의 끝을 나타내는 앵커  |
 +^ ?  | 물음표  | U+003F  | 0번 또는 한 번을 나타내는 수량자  |
 +^ *  | 별표  | U+002A  | 0번 이상을 나타내는 수량자  |
 +^ +  | 덧셈 기호  | U+002B  | 한 번 이상을 나타내는 수량자  |
 +^ [  | 왼쪽 대괄호  | U+005B  | 문자 클래스 시작  |
 +^ ]  | 오른쪽 대괄호  | U+005D  | 문자 클래스 끝  |
 +^ {  | 왼쪽 중괄호  | U+007B  | 수량자 또는 블록 시작  |
 +^ }  | 오른쪽 중괄호  | U+007D  | 수량자 또는 블록 끝  |
 +^ (  | 왼쪽 소괄호  | U+0028  | 그룹 시작  |
 +^ )  | 오른쪽 소괄호  | U+0029  | 그룹 끝  |
 +
 +
  
 ==== 숫자 ==== ==== 숫자 ====
Line 19: Line 38:
  
 ^  단축 문자((이 외에 더 있음, 정규표현식 엔진에 따라 지원 여부 다양))  ^^ ^  단축 문자((이 외에 더 있음, 정규표현식 엔진에 따라 지원 여부 다양))  ^^
 +^ 단축문자  ^ 설명  ^
 ^ \a  | 벨 문자  | ^ \a  | 벨 문자  |
 ^ [\b]  | 백스페이스 문자  | ^ [\b]  | 백스페이스 문자  |
Line 50: Line 70:
  
 ==== 참조 그룹 ==== ==== 참조 그룹 ====
-  * 찾고자 하는 내용을 ()로 감싼 후(참조) $1, $2 혹은 \1, \2와 같이 역참조+  * 찾고자 하는 내용을 ()로 감싼 후(참조) \$1, \$2 혹은 \1, \2와 같이 역참조
  
  
Line 80: Line 100:
  
 ^  정규표현식 옵션((서브패턴 이름 지정은 http://www.pcre.org/pcre.txt 참고))  ^^^ ^  정규표현식 옵션((서브패턴 이름 지정은 http://www.pcre.org/pcre.txt 참고))  ^^^
 +^ 옵션  ^ 설명  ^ 지원  ^
 ^ (?d)  | 유닉스 행  | 자바  | ^ (?d)  | 유닉스 행  | 자바  |
 ^ (?i)  | 대소문자 구분 없앰  | PCRE, Perl, 자바  | ^ (?i)  | 대소문자 구분 없앰  | PCRE, Perl, 자바  |
Line 91: Line 112:
  
 ^  Perl 변경자(플래그)((http://perldoc.perl.org/perlre.html#Modifiers 참고))  ^^ ^  Perl 변경자(플래그)((http://perldoc.perl.org/perlre.html#Modifiers 참고))  ^^
 +^ 변경자  ^ 설명  ^
 ^ a  | \d, \s, \w 및 ASCII 범위 내의 POSIX 문자  | ^ a  | \d, \s, \w 및 ASCII 범위 내의 POSIX 문자  |
 ^ c  | 찾기 실패 후 현재 위치 유지  | ^ c  | 찾기 실패 후 현재 위치 유지  |
Line 109: Line 131:
  
 ^  그룹 이름 지정 구문  ^^ ^  그룹 이름 지정 구문  ^^
 +^ 구문  ^ 설명  ^
 ^ (?<name>...)  | 그룹 이름 지정  | ^ (?<name>...)  | 그룹 이름 지정  |
 ^ (?name...)  | 또 다른 그룹 이름 지정  | ^ (?name...)  | 또 다른 그룹 이름 지정  |
Line 131: Line 154:
 ==== POSIX 문자 클래스 ==== ==== POSIX 문자 클래스 ====
 ^  POSIX 문자 클래스  ^^ ^  POSIX 문자 클래스  ^^
-^ [[:alnum:]]  | 영문자와 숫자 +문자 클래스  ^ 설명 
-^ [[:alpha:]]  | 알파벳 문자(영문자) +^ <nowiki>[[:alnum:]]</nowiki>  | 영문자와 숫자 
-^ [[:ascii:]]  | ASCII 문자(모두 128)  | +<nowiki>[[:alpha:]]</nowiki>  | 알파벳 문자(영문자) 
-^ [[:blank:]]  | 빈 문자 +<nowiki>[[:ascii:]]</nowiki>  | ASCII 문자(모두 128)  | 
-^ [[:ctrl:]]  | 제어 문자 +<nowiki>[[:blank:]]</nowiki>  | 빈 문자 
-^ [[:digit:]]  | 숫자 +<nowiki>[[:ctrl:]]</nowiki>  | 제어 문자 
-^ [[:graph:]]  | 그래픽 문자 +<nowiki>[[:digit:]]</nowiki>  | 숫자 
-^ [[:lower:]]  | 소문자 +<nowiki>[[:graph:]]</nowiki>  | 그래픽 문자 
-^ [[:print:]]  | 인쇄 가능한 문자 +<nowiki>[[:lower:]]</nowiki>  | 소문자 
-^ [[:punct:]]  | 구두점 문자 +<nowiki>[[:print:]]</nowiki>  | 인쇄 가능한 문자 
-^ [[:space:]]  | 공백 문자 +<nowiki>[[:punct:]]</nowiki>  | 구두점 문자 
-^ [[:upper:]]  | 대문자 +<nowiki>[[:space:]]</nowiki>  | 공백 문자 
-^ [[:word:]]  | 단어 +<nowiki>[[:upper:]]</nowiki>  | 대문자 
-^ [[:xdigit:]]  | 16진수  |+<nowiki>[[:word:]]</nowiki>  | 단어 
 +<nowiki>[[:xdigit:]]</nowiki>  | 16진수  |
  
  
  
 ===== 유니코드와 기타 문자 ===== ===== 유니코드와 기타 문자 =====
 +  * \u16진수코드; \u00e9, \xe9
 +  * 8진수로 문자 찾기; \351(==\u00e9)
 +  * 제어문자 찾기; /cx
 +
  
 ===== 수량자 ===== ===== 수량자 =====
 +  * 욕심많고, 게으르고, 독점적인 수량자
 +  * 욕심쟁이; 입력된 텍스트에서 가능한 많은 부분, 즉 전체 문자열을 가져온 다음 원하는 문자열을 찾아내려고 시도.
 +  * 게으른(또는 느슨한) 수량자; 우선 문자열의 시작 위치부터 검색. 원하는 문자열을 찾을 때까지 하나씩 문자를 증가시키면서 찾다가, 계속 찾지 못하면 마지막으로 전체 텍스트를 검사. 일반 수량자 뒤에 물음표(?)를 붙인다.
 +  * 독점적인 수량자; 전체 텍스트를 가져온 후, 찾고자 하는 문자열인지를 검사. 오직 한 번만 시도, 백트래킹은 하지 않음. 일반 수량자 뒤에 덧셈기호(+)를 붙인다.
 +  * 클리니 스타(*)
 +  * *, +, ?
 +
 +^  기본 수량자  ^^
 +^ 구문  ^ 설명  ^
 +^ ?  | 0 또는 하나  |
 +^ +  | 하나 이상  |
 +^ *  | 0 또는 그 이상  |
 +
 +^  게으른 수량자  ^^
 +^ 구문  ^ 설명  ^
 +^ ??  | 게으르게 0번 또는 한 번  |
 +^ +?  | 게으르게 한 번 이상  |
 +^ *?  | 게으르게 0번 이상  |
 +^ {n}?  | 게으르게 n번  |
 +^ {n.}?  | 게으르게 n번 이상  |
 +^ {m,n}?  | 게으르게 m부터 n까지  |
 +
 +^  독정적인 수량자  ^^
 +^ 구문  ^ 설명  ^
 +^ ?+  | 독점적으로 0번 또는 한 번  |
 +^ ++  | 독점적으로 한 번 이상  |
 +^ *+  | 독점적으로 0번 이상  |
 +^ {n}+  | 독점적으로 n번  |
 +^ {n.}+  | 독점적으로 n번 이상  |
 +^ {m,n}+  | 독점적으로 m에서 n까지  |
 +
 +
 +
 +===== 탐색 =====
 +  * lookaround
 +  * 긍정형 전방 탐색(Positive lookaheads)
 +  * 부정형 전방 탐색(Negative lookaheads)
 +  * 긍정형 후방 탐색(Positive lookbehinds)
 +  * 부정형 후방 탐색(Negative lookbehinds)
  
 ===== 자주 쓰는 정규표현식 ===== ===== 자주 쓰는 정규표현식 =====
Line 187: Line 254:
     - -가 2개 이상     - -가 2개 이상
     - >로 닫음      - >로 닫음 
 +
 +  * <del>이름 masking; <alert type="info"><nowiki>(JAVA) str.replaceFirst("(\\W)\\W+\$", "\$1*****"))</nowiki></alert></del>
 +  * 숫자를 제외한 모든 문자 제거; <alert type="info"><nowiki>(JAVA) strConverted = str.replaceAll("\\D", "");</nowiki></alert>
 +  * 숫자만으로 되어있는 사업자 번호 -> 사업자번호 형식; <alert type="info"><nowiki>(JAVA) strConverted = str.replaceFirst("(^\\d{3})(\\d{2})(\\d{5})\$", "\$1-\$2-\$3");</nowiki></alert>
 +  * 숫자만으로만 되어있는지 확인; <alert type="info"><nowiki>(JAVA) bDigitsOnly = str.matches("^\\d+\$");</nowiki></alert>
 +  * 첫글자만 보이게 마스킹; <alert type="info"><nowiki>(JAVA) strMasked = str.replaceFirst("(^\\S)\\S+\$", "\$1*****");</nowiki></alert>
 +  * Password Validataions (JAVA & TypeScript)<sxh java title:Password Validation for JAVA>
 +
 +    public static Boolean hasSpecialCharacter(String strPassword) 
 +    {
 +        Boolean bHasSpecialCharacter = Pattern.matches("^(?=.*[\\x21-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7e]).{1,}", strPassword);
 +
 +        if(true == bHasSpecialCharacter)
 +        {
 +            System.out.println(strPassword + " has Special Character.");
 +        }
 +        else
 +        {
 +            System.out.println(strPassword + " has no Special Character.");
 +        }
 +
 +        return bHasSpecialCharacter;
 +    }
 +
 +    public static Boolean isValidPassword(String strPassword) 
 +    {
 +        Boolean bValid = Pattern.matches("^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\\x21-\\x2f|\\x3a-\\x40|\\x5b-\\x60|\\x7b-\\x7e]).{10,16}", strPassword);
 +
 +        System.out.println(strPassword + ":" + bValid);
 +        return bValid;
 +    }
 +
 +    public static Boolean hasAlphabet(String strPassword) 
 +    {
 +        Boolean bHasAlphabet = Pattern.matches("^(?=.*[a-zA-Z]).{1,}", strPassword);
 +
 +        if(true == bHasAlphabet) 
 +        {
 +            System.out.println(strPassword + " has Alphabet.");
 +        }
 +        else
 +        {
 +            System.out.println(strPassword + " has no Alphabet.");
 +        }
 +
 +        return bHasAlphabet;
 +    }
 +
 +    public static Boolean hasDigit(String strPassword)
 +    {
 +        Boolean bHasDigit = Pattern.matches("^(?=.*[\\d]).{1,}", strPassword);
 +
 +        if(true == bHasDigit)
 +        {
 +            System.out.println(strPassword + " has Digits.");
 +        }
 +        else
 +        {
 +            System.out.println(strPassword + " has no Digits.");
 +        }
 +
 +        return bHasDigit;
 +    }
 +
 +    public static void testPassword(String strPassword)
 +    {
 +        System.out.println("Your password is : " + strPassword);
 +
 +        hasAlphabet(strPassword);
 +        hasDigit(strPassword);
 +        hasSpecialCharacter(strPassword);
 +    }</sxh><sxh typescript title:Password Validation for TypeScript>
 +function hasAlphabet(strPassword: string) {
 +  const reg = new RegExp("^(?=.*[a-zA-Z]).{1,}$")
 +  const bHasAlphabet = reg.test(strPassword)
 +
 +  if(false === bHasAlphabet) {
 +    console.log(`${strPassword} has no alphabet.`)
 +  } else {
 +    console.log(`${strPassword} has alphabet.`)
 +  }
 +    
 +  return bHasAlphabet
 +}
 +
 +function hasDigit(strPassword: string) {
 +  const reg = new RegExp("^(?=.*[0-9]).{1,}$")
 +  const bHasDigit = reg.test(strPassword)
 +
 +  if(false === bHasDigit) {
 +    console.log(`${strPassword} has no digit.`)
 +  } else {
 +    console.log(`${strPassword} has digit.`)
 +  }
 +
 +  return bHasDigit
 +}
 +
 +function hasSpecialCharacter(strPassword: string) {
 +  const reg = new RegExp("^(?=.*[\\x21-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7e]).{1,}$")
 +  const bHasSpecialCharacter = reg.test(strPassword)
 +
 +  if(false === bHasSpecialCharacter){
 +    console.log(`${strPassword} has no special character.`)
 +  } else {
 +    console.log(`${strPassword} has special character.`)
 +  }
 +
 +  return bHasSpecialCharacter
 +}
 +
 +function isValidPassword(strPassword: string) {
 +  const reg = new RegExp("^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\\x21-\\x2f|\\x3a-\\x40|\\x5b-\\x60|\\x7b-\\x7e]).{10,16}$")
 +  const bValid = reg.test(strPassword)
 +
 +  if(false === bValid) {
 +    console.log(`${strPassword} is invalid.`)
 +  } else {
 +    console.log(`${strPassword} is valid.`)
 +  }
 +
 +  return bValid
 +}
 +
 +function testPassword(strPassword: string) {
 +  console.log(`Your Password is : ${strPassword}`)
 +
 +  hasAlphabet(strPassword)
 +  hasDigit(strPassword)
 +  hasSpecialCharacter(strPassword)
 +
 +  isValidPassword(strPassword)
 +
 +}</sxh>
 +  * camelCase to snake_case and MACRO_CASE (JAVA)<sxh java title:camelCase to snake_case and MACRO_CASE for JAVA>
 +    public static String getSnakeCaseFromCamelCase(String strCamelCase)
 +    {
 +        return strCamelCase.replaceAll("([A-Z])", "_$1").toLowerCase();
 +    }
 +
 +    public static String getMacroCaseFromCamelCase(String strCamelCase) 
 +    {
 +        return strCamelCase.replaceAll("([A-Z])", "_$1").toUpperCase();
 +    }
 +</sxh>
 +  * Card Number Validation (TypeScript)<sxh typescript title:Card Number Validation Example for TypeScript>
 +function validateIBKCEOCard(strCardNumber: string) {
 +  const regDigitsOnly = /(\D+)/gi
 +  const strDigits = strCardNumber.replace(regDigitsOnly, "")
 +
 +  if (strDigits.length != 16) {
 +    console.log(strCardNumber + ' is invalid card number')
 +    return
 +  }
 +  
 +  console.log('validate IBK CEO Card: ' + strCardNumber + ' => ' + strDigits + '(' + strDigits.length + ')')
 +
 +  const regValidate: RegExp = /^943003|^552103\d+$/g
 +  const bValid = regValidate.test(strDigits)
 +
 +  console.log('is valid? ' + bValid)
 +}
 +</sxh>
 +
  
  
 ===== Tools ===== ===== Tools =====
 +
 +==== 프로그램과 라이브러리 ====
 +  * Perl
 +  * PCRE(Perl Compatible Regular Expression)
 +  * 루비에서 사용하는 오니구루마
 +  * 파이썬
 +  * RE2
 +
 +
 ==== On-line ==== ==== On-line ====
   * [[https://www.regexpal.com/|RegEx Pal]]   * [[https://www.regexpal.com/|RegEx Pal]]
   * [[https://regexr.com/|RegExr]]   * [[https://regexr.com/|RegExr]]
-  * rubular+  * [[https://rubular.com/|Rubular]]
  
  
Line 207: Line 447:
   * [[https://www.oxygenxml.com/|Oxygen XML Editor]]   * [[https://www.oxygenxml.com/|Oxygen XML Editor]]
   * reggy   * reggy
 +
 +
 +===== References =====
 +  * [[https://jamesdreaming.tistory.com/182|[ 자바 코딩 ] REGULAR EXPRESSION 정규표현식 - 숫자만 허용하기]]
 +  * [[https://coding-factory.tistory.com/529|[Java] 자바 정규 표현식 (Pattern, Matcher) 사용법 & 예제]]
 +  * [[https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_Expressions|정규 표현식]]
 +  * [[https://apiclass.tistory.com/entry/%EC%8B%A4%EC%A0%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%A0%95%EA%B7%9C%EC%8B%9D-%ED%8C%A8%ED%84%B4|실제 사용하는 정규식 패턴]]
 +  * [[https://intro0517.tistory.com/135|자바스크립트 정규식 정리(숫자만, 한글만, 메일, 전화번호, 비밀번호)]]
 +  * [[https://develop-sense.tistory.com/62|[JAVA] 정규식을 이용한 마스킹(정규표현식 마스킹 처리)]]
 +  * [[https://leejiheg.tistory.com/entry/%EC%A0%95%EA%B7%9C-%ED%91%9C%ED%98%84%EC%8B%9D-%EA%B8%B0%EB%B3%B8|정규 표현식 기본]]
 +  * [[https://youngjinmo.github.io/2020/01/reg/|정규표현식(Reg)]]
 +  * [[https://minj0i.tistory.com/26|[JAVA] 이름 마스킹처리]]
 +  * [[https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html|Class Pattern]]
 +  * [[https://blog.naver.com/PostView.nhn?blogId=realuv&logNo=220699272999|[Javascript] 정규식을 이용한 특수문자, 한글 등 특정 문자 체크(제거)]]
 +
 +
 +
 +
 +
 +
  • public/computer/regexp.txt
  • Last modified: 2023/01/01 00:58
  • by alex