programing

MariaDB/Mediawiki의 다중 행 정규식 일치

sourcetip 2022. 12. 7. 00:26
반응형

MariaDB/Mediawiki의 다중 행 정규식 일치

MariaDB 10.3.22를 실행하고 있는 MW 1.31의 Replace Text 확장을 통해 여러 줄의 텍스트(Mediawiki 템플릿에 포함)를 대조하려고 합니다.

템플릿의 예는 다음과 같습니다(같은 페이지에 다른 템플릿이 존재할 수 있습니다).

{{WoodhouseENELnames
|Text=[[File:woodhouse_999.jpg|thumb|link={{filepath:woodhouse_999.jpg}}]]Αἰακός, ὁ, or say, son of Aegina.

<b class="b2">Of Aeacus</b>, adj.: Αἰάκειος.

<b class="b2">Descendant of Aeacus</b>: Αἰακίδης, -ου, ὁ.
}}

위와 아래는 줄 바꿈의 수가 다른 다른 템플릿일 수 있습니다.

{{MyTemplatename
|Text=text, text, text
}}
{{WoodhouseENELnames
|Text=text, text, text
}}
{{OtherTemplatename
|Text= text, text, text
}}

템플릿 내에는 줄 바꿈 또는 줄 바꿈의 수가 다양합니다.완전한 템플릿을 대조하여 삭제하고 싶다.그것이 일치하고 있는 것은,{{WoodhouseENELnames끝까지}}단, 더 아래쪽에 있는 템플릿을 매칭하지 않고, 즉 더 아래쪽에 있는 경우 매칭을 중지합니다.{{가 검출되었습니다.

가장 근접한 것은 다음과 같은 것을 사용하는 것이었습니다.

검색({{WoodhouseENELnames\n\|Text=)(.*?)\n+(.*?)\n+(.*?)\n+(.*?)(\n+}})

추가/삭제(.*?)\n+대소문자를 대소문자와 일치시킵니다.문제는 이 표현식이 실수로 이 표현식 이후의 다른 템플릿과 일치할 수 있다는 것입니다.

같은 페이지의 템플릿에 포함되는 모든 텍스트/행 구분과 일치하는 정규식이 있습니까(아래와 위에 다른 템플릿이 있을 수 있으므로 느긋하게 표시).템플릿은 를 열어 구분합니다.{{및 클로징후}})?

혼동을 해소하기 위해 편집


이것은 다음에서 사용하기 위한 재귀 시뮬레이션입니다.
함수 호출을 지원하지 않는 Java, Python 스타일 엔진(재귀)

(?s)(?={{WoodhouseENELnames)(?:(?=.*?{{(?!.*?\1)(.*}}(?!.*\2).*))(?=.*?}}(?!.*?\2)(.*)).)+?.*?(?=\1)(?:(?!{{).)*(?=\2$)

재귀 시뮬레이션 데모

일치하는 항목만 확인하면 됩니다.


이것은 Perl, PCRE 스타일의 엔진에서 사용하는 실제 재귀입니다.

(?s){{WoodhouseENELnames((?:(?>(?:(?!{{|}}).)+)|{{(?1)}})*)}}

재귀 데모


Dot-Net은 다른 방식으로 수행되며 여기에 포함되지 않습니다.

재귀 쿼리를 사용한 무차별적이고 반복적인 접근법만 생각할 수 있습니다.

이 아이디어는 현악기 부분이 처음 발생한 시점부터 현악기 사이를 걸어가는 것입니다.'{{WoodhouseENELnames'그 후, 개폐 브래킷의 수를 기록하는 카운터를 설정할 수 있습니다.카운트가 도달했을 때0패턴이 고갈된 것을 알 수 있습니다.마지막 단계는 패턴 전후의 부품을 유지하는 문자열을 재구축하는 것입니다.

이렇게 하려면 각 행을 식별할 고유한 열이 필요합니다.나는 추측했다id.

with recursive cte as (
    select 
        n_open n0,
        n_open n1,
        1 cnt,
        mycol,
        id
    from (select t.*, locate('{{WoodhouseENELnames', mycol) n_open from mytable t) x
    where n_open > 0
    union all 
    select 
        n0,
        n1 + 2 + case when n_open > 0 and n_open < n_close then n_open else n_close end,
        cnt + case when n_open > 0 and n_open < n_close then 1 else -1 end,
        mycol,
        id
    from (
        select 
            c.*,
            locate('{{', substring(mycol, n1 + 2)) n_open,
            locate('}}', substring(mycol, n1 + 2)) n_close
        from cte c
    ) x
    where cnt > 0
)
select id, concat(substring(mycol, 1, min(n0) - 1), substring(mycol, max(n1) + 1)) mycol
from cte
group by id

DB 바이올린 데모

셋업 - 패턴 전후로 스트링 부분을 추가했습니다(더 재미있게 하기 위해 이중 괄호 포함).

create table mytable(id int, mycol varchar(2000));
insert into mytable values (
    1,
    '{{abcd{{WoodhouseENELnames
|Text=[[File:woodhouse_999.jpg|thumb|link={{filepath:woodhouse_999.jpg}}]]Αἰακός, ὁ, or say, son of Aegina.

<b class="b2">Of Aeacus</b>, adj.: Αἰάκειος.

<b class="b2">Descendant of Aeacus</b>: Αἰακίδης, -ου, ὁ.
}} efgh{{'
);

결과:

id | mycol-: | :------------1 | {{abcd efgh†

MariaDB는 PCRE-Regex 엔진을 사용합니다.

당신이 장담할 수긍정할 수 있다면

  1. (「Topening Tag」(「Topening Tag」(「Topening Tag」){{WoodhouseENELnames
  2. (「」)}}
  3. 닫힘태그 }}새로운 행으로 시작하는 사이에 Regex는 다음 작업을 수행합니다.
(?ms)^{{WoodhouseENELnames.+?^}}

설명:

  1. (?ms)을 말하다^ 내의 의 줄 합니다..을 사용하다
  2. 그런 다음 새 줄에서 시작 태그를 검색하십시오.
  3. 가능한 최단 문자열 검색(최대 줄 바꿈)
  4. 꼬리표}}새로운 회선에 접속합니다.

내용을 를 "regex" 안에 .( ★★★★★★★★★★★★★★★★★」)

편집:

PCRE2는 재귀 패턴을 지원하므로 위의 beginnig-of-line-constraint에 관계없이 다음 보다 복잡한 regex가 일치합니다.

(?msx)
({{WoodhouseENELnames       # group 1: Matching the whole template
    (                       # group 2: Mathing the contents of the Template, including subpatters.
        [^{}]*              # Search zewro or more characters except { or }
        {{                  # The beginning of a subpattern
        (                   # Containg if:
            [^{}]++         # Search zewro or more characters except { or }
        |   (?2)            # or the recursive pattern group 2
        )*                  # Zero or more times
        }}                  # The closing of the subpattern.
        [^{}]*              # Search zewro or more characters except { or }
    )
    }}
)

싱글은 하지 않습니다.{ ★★★★★★★★★★★★★★★★★」}템플릿에 포함시킵니다.

편집 2

작업이 완료되기 전에 포기하는 것은 질색입니다:-) 이 regex는 위의 모든 조건에 관계없이 동작해야 합니다.

(?msx)                  # Note the additional 'x'-Option, allowing free spacing.
({{WoodhouseENELnames   # Searcdh group 1 - Top level template:
    (                   #  Search group 2 - top level template contents:
        (               #   Search-group 3 - Subtemplate contents:
            [^{}]*      #    Zero or more characters except { or }
        |   {(?!{)      #    or a single { not follwed by a {
        |   }(?!})      #    or a single } not follwed by a }
        )*              #   Closing search group 3
        {{              #  Opening subtemplate tag
        (               #  Search group 4:
            (?3)*       #   Reusing serach group 3, zero or more times
        |   (?2)        #   or Recurse search group 2 (of which, this is a part)
        )*              #  Group 4 zero or more times
        }}              #  Closing subtemplate tag
        (?3)*           #  Reusing search group 3, zero or more times
    )                   #  Closing Search group 2 - Template contents
    }}                  #  Top-level Template closing tag
)                       # Closing Search group 1

마지막 2개의 솔루션은 PCRE2 매뉴얼에 근거하고 있습니다.

언급URL : https://stackoverflow.com/questions/61406318/multiline-regex-match-in-mariadb-mediawiki

반응형