중첩 된 문자열을 구문 분석하거나 HTML을 실제 파서로 처리하는 것이 더 좋지만 제 경우에는 간단한 템플릿이 있고 Wiki의 제목 내용을 추출하고 싶습니다. 템플릿에서 'title'매개 변수 이 문제를 해결하는 데는 시간이 걸렸지 만, Lars Olav Torvik (http://regex.larsolavtorvik.com/)의 정규식 도구 덕분에이 사용자 포럼은 여기에 있습니다. 누군가 유용 할 수 있습니다. (우리 모두는 기여하기를 원합니다, 그는 그렇지 않습니까?) 코멘트로 주석 된 다음 코드는 트릭을 수행합니다. 그 중 하나에 제목이 없으면 두 개의 템플릿을 함께 사용하지 않기 위해 어설 션을 둘러 봐야했습니다.균형 잡힌 중첩 된 wiki 템플릿을 구문 분석하고 정규식을 사용하여 단일 행 매개 변수의 내용 추출
정규식 주석의 두 가지 질문에 대해 아직 확신하지 않습니다. (?R)
에서 재귀 부분을 이해하면 (?# Questions: …)
을 참조하십시오. 그것은 가장 바깥에 정의 된 수준, 즉 두 번째 정규식 줄 \{\{
과 마지막 정규식 줄 \}\}
에서 확인할 내용을 가져옵니다. 그것이 맞을까요? (?R)
부스의 대안이 똑같이 작동하기 전에 ++
과 +
의 차이점은 무엇입니까?
(가장 간단한) 페이지에 origninal 위키 템플릿 :
$wikiTemplate = " {{Templ1 | title = (1. template) title }} {{Templ2 | any parameter = something {{template}} }} {{Templ1 | title = (3. template) title }} ";
교체 :
$wikiTemplate = preg_replace( array( // tag all templates with START … END and add a TITLE-placeholder before // and take care of balanced {{ … }} recursiveness "@(?s) (?# switch to dotall match, i.e. also linebreaks) \{\{ (?# find two {{) (?: (?# group 1 as a non-backreferenced match ) (?: (?# group 2 as a non-backreferenced match ) (?! (?# in group 1 anything but not {{ or }}) \{\{ | (?# or) \}\} ) . )++ (?# Question: what is the differenc between ++ and + here?) | (?# or) (?R) (?# is it recursive of what is defined in the outermost, i.e. 2nd regexp line with \{\{ and last line with \}\} Question: is that here understood correctly?) ) * (?# zero or many times of the inner regexp defintions) \}\} (?# find two }}) @x",// x-extended → ignore white space in the pattern // replace TITLE by single line content of title parameter "@ (?<=TITLE) (?# TITLE must preceed the following linebreak but is not backreferenced within \\0, i.e. the whole returned match) ([\n\r]+) (?#linebr in 1 may also described as . because of s-modifier dotall) (?: (?# start non-backreferenced match) . (?# any character but not followed by START) (?!START) )+ (?# multiple times) (?: (?# start non-backreferenced match) \|\s*title\s*=\s* (?#find the parameter '| title = ') ) ([^\r\n]+) (?#get title now to \\2 but exclude the line break. Note it is buggy when there is no line break) (?: (?# start non-backreferenced match) . (?# any character but not followed by END) (?!END) ) + (?# multiple times) . (?# any single character, e.g. the last because as all stuff before captures anything not followed by END) (?:END) (?#a not backreferenced END) @msx", // m-multiline, s-dotall match also linebreaks, // x-extended → ignore white space in the pattern ), array( "TITLE\nSTART\\0END", // \0 is the whole returned match, i.e. the template # replace the TITLE to TITLEtitle contentTITLE… "\\2TITLE\\0", ), $wikiTemplate ); print_r($wikiTemplate);
출력은 제목 태그 제목으로 다음이다 제목이있는 경우에만 각 템플릿 위 :
,363,210 내 정규 표현식 이해에 대한 질문, 또는 개선을위한TITLE(1. template) titleTITLE START{{Templ1 | title = (1. template) title }}END TITLE START{{Templ2 | any parameter = something {{template}} }}END TITLE(3. template) titleTITLE START{{Templ1 | title = (3. template) title }}END
모든 내부? 감사합니다. Andreas.
오직이 질문이 얼마나 오래되었는지 깨닫습니다 ... –
어쨌든 고맙습니다 .--) 질문의 길이는 중요하지 않습니다. –