정규식 유효성 검사 정규식 [닫기]


17

정규식 문자열을 입력으로 받아들이고 유효한지 확인하는 정규식을 작성하십시오. 기본적으로 정규식은 자체적으로 유효성을 검사 할 수 있어야합니다. (유효하지 않은 정규 표현식은 유효성을 검사해서는 안되므로 .*.;을 사용할 수 없습니다 .)

플레이버는 잘 알려진 구현 (Perl, sed, grep, gawk 등)으로 완전히 지원되어야하며 해당 구현이 지원하는 것을 완전히 지원해야합니다. [변호사 이야기에 대해 걱정하지 마십시오. 똑똑한 사람들을 위해 가능한 허점을 제거하려고합니다.]


나는 그것을 로 만들지 만, 비 기능이 풍부한 풍미를 알고 사용하는 사람들에게 우위를 줄 것이라고 걱정합니다. 아니면 내 근심이 근거가 없는가?


8
불가능한 임의의 중첩 괄호는 정규 표현식에 컨텍스트 프리 문법을 만듭니다 (폴란드어 표기법으로 바꾸려면 스택이 필요합니다)
ratchet freak

@ratchet Augh, 당신이 옳을 수도 있습니다.
Mateen Ulhaq

1
일반 언어에는 대괄호와 일치하는 확장이 있지만 어떻게해야할지 모르겠습니다.
ratchet freak

8
Perl 정규식으로 가능할 것입니다.
피터 테일러

1
현대 언어로 구현 된 @BrianVandenberg 정규식은 거의 모든 비정규 식입니다. 역 참조를 추가하자마자 비정규 언어를 일치시킬 수 있습니다. 또한 Perl / PCRE와 .NET은 정확한 네 스팅과 일치 할만큼 강력합니다.
Martin Ender 2016 년

답변:


22

루비

나는 가능한 한 루비의 정규식 맛의 실제 구문을 일치하려고하지만 몇 가지 단점이 있습니다 : 그것은 (같은 사실은 유효하지 않은 몇 lookbehinds을 받아 (?<=(?<!)))과 같은 빈 문자 범위를 인식합니다 D-A. 후자는 ASCII로 수정 될 수 있지만 정규 표현식은 그 자체로 충분히 길다.

\A(?<main>
    (?!
        \{(\d+)?,(\d+)?\} # do not match lone counted repetition
    )
    (?:
        [^()\[\]\\*+?|<'] | # anything but metacharacters
        (?<cclass>
            \[ \^? (?: # character class
                (?: # character class
                    [^\[\]\\-] | # anything but square brackets,  backslashes or dashes
                    \g<esc> |
                    \[ : \^? (?: # POSIX char-class
                        alnum | alpha | word | blank | cntrl | x?digit | graph | lower | print | punct | space | upper
                    ) : \] |
                    - (?!
                        \\[dwhsDWHS]
                    ) # range / dash not succeeded by a character class
                )+ |
                \g<cclass> # more than one bracket as delimiter
            ) \]
        ) |
        (?<esc>
            \\[^cuxkg] | # any escaped character
            \\x \h\h? | # hex escape
            \\u \h{4} | # Unicode escape
            \\c . # control escape
        ) |
        \\[kg] (?:
            < \w[^>]* (?: > | \Z) |
            ' \w[^']* (?: ' | \Z)
        )? | # named backrefs
        (?<! (?<! \\) \\[kg]) [<'] | # don't match < or ' if preceded by \k or \g
        \| (?! \g<rep> ) | # alternation
        \( (?: # group
            (?:
                \?
                (?:
                    [>:=!] | # atomic / non-capturing / lookahead
                    (?<namedg>
                        < [_a-zA-Z][^>]* > |
                        ' [_a-zA-Z][^']* ' # named group
                    ) |
                    [xmi-]+: # regex options
                )
            )?
            \g<main>*
        ) \) |
        \(\?<[!=] (?<lbpat>
            (?! \{(\d+)?,(\d+)?\} )
            [^()\[\]\\*+?] |
            \g<esc>  (?<! \\[zZ]) |
            \g<cclass> |
            \( (?: # group
                (?:
                    \?: |
                    \? \g<namedg> |
                    \? <[!=]
                )?
                \g<lbpat>*
            ) \) |
            \(\?\# [^)]* \)
        )* \)
        |
        \(\? [xmi-]+ \) # option group
        (?! \g<rep> ) 
        |
        \(\?\# [^)]*+ \) # comment
        (?! \g<rep> )
    )+
    (?<rep>
        (?:
            [*+?] | # repetition
            \{(\d+)?,(\d+)?\} # counted repetition
        )
        [+?]? # with a possessive/lazy modifier
    )?
)*\Z

읽을 수없는 버전 :

\A(?<main>(?!\{(\d+)?,(\d+)?\})(?:[^()\[\]\\*+?|<']|(?<cclass>\[\^?(?:(?:[^\[\]\\-]|\g<esc>|\[:\^?(?:alnum|alpha|word|blank|cntrl|x?digit|graph|lower|print|punct|space|upper):\]|-(?!\\[dwhsDWHS]))+|\g<cclass>)\])|(?<esc>\\[^cuxkg]|\\x\h\h?|\\u\h{4}|\\c.)|\\[kg](?:<\w[^>]*(?:>|\Z)|'\w[^']*(?:'|\Z))?|(?<!(?<!\\)\\[kg])[<']|\|(?!\g<rep>)|\((?:(?:\?(?:[>:=!]|(?<namedg><[_a-zA-Z][^>]*>|'[_a-zA-Z][^']*')|[xmi-]+:))?\g<main>*)\)|\(\?<[!=](?<lbpat>(?!\{(\d+)?,(\d+)?\})[^()\[\]\\*+?]|\g<esc>(?<!\\[zZ])|\g<cclass>|\((?:(?:\?:|\?\g<namedg>|\?<[!=])?\g<lbpat>*)\)|\(\?#[^)]*\))*\)|\(\?[xmi-]+\)(?!\g<rep>)|\(\?#[^)]*+\)(?!\g<rep>))+(?<rep>(?:[*+?]|\{(\d+)?,(\d+)?\})[+?]?)?)*\Z

28
읽을 수없는 버전이 아닌가?
Kibbee

2
@Kibbee 첫 번째 규칙은 정규식을 잘 알고 있으면 읽을 수 있습니다.
Lowjacker

1
이렇게하면 유효하지 않은 숫자 역 참조가 없는지 어떻게 알 수 있습니까?
Martin Ender 2016 년

1
나는 그렇지 않다고 생각합니다. 다시 한 번, 이것이 유일한 제한은 아닙니다 (위 참조). 어떤 것들이 고칠 수는 있지만 정규 표현식은 엄청나게 길어질 것입니다.
Lowjacker
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.