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


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.