2016-08-02 2 views
1

요구 사항에 맞는 정규식을 찾으려고했지만 찾을 수 없습니다. 누구든지이 문제를 발견하면 저를 도와주세요.다른 패턴 안에있을 때 패턴을 제외하십시오

예를 들어 html 주석이 JSP 주석 내에있는 경우이를 만지지 마십시오. 그렇지 않으면 JSP 주석으로 만듭니다.

Condition: 1 
<!-- normal HTML comment --> 

with 

<%-- normal HTML comment --%> 

그러나 아래와 같이 JSP 주석 내부의 HTML 주석과 일치하지 않습니다.

Codition: 2 
<%-- normal JSP comment 

    <!-- inside html comment here --> 
     other comment stuff 
<!-- another inside html comment here --> 

--%> 

자바 솔루션에 크게 감사드립니다.

+1

는 "나는 내 요구 사항에 대한 정규식을 찾기 위해 노력했다,하지만 난 하나를 찾을 수 없습니다." - 정규 표현식이 HTML과 같은 비정규 문제 영역에 적합하지 않은 이유의 예입니다 (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self -contained-tags/1732454 # 1732454) 등등. 조건 1과 2를 다루는 표현식을 만들 수 있습니다. (상당히 복잡 할 수도 있습니다.) 그리고 조건 3을 만나게됩니다. 문제 영역을 이해하는 파서를 사용하십시오. (귀하의 경우 JSP 코드). – Thomas

+0

이것이 html과 JSP가 혼합 된 것이라면 그 이상이 필요할 것입니다. 그것은 혼합인가? – sln

+0

@sln 예입니다. – kakurala

답변

1

컨텍스트 "X"또는 컨텍스트 "Y"가 아닌 항목과 일치 시키려 할 때 나는 항상 The Greatest Regex Trick Ever의 수식을 사용합니다. 트릭은 원하는 것을 가지고있는 교대의 가장 오른쪽에있는 캡쳐 그룹을 만들고 교대의 왼쪽에 원하지 않는 다른 모든 상황을 만드는 것입니다.

또한 정규 표현식은 문자열 리터럴을 무시해야합니다. 귀하의 정규식과 같습니다

".*?(?<!\\)"|(?s)<%--.*?--%>|<!--(.*?)--> 

그리고 첫 번째 캡처 그룹이있는 경우 다음 코드는 문자열을 대체 할 것이다.

Ideone Demo

+0

그런 패턴이 n 개 있다고 가정하면 조건/표현식의 조합이 복잡해집니다. 이 바로 가기? – JavaHopper

+1

@JavaHopper 여러 컨텍스트를 무시하려면 광고 보관하기 만하면됩니다. 왼쪽에 땡땡이 치기. 그래서 '아니다! 이쪽은 (잘) 이쪽! (우리)' – 4castle

+0

트릭 @ 4 캐슬을 가져 주셔서 감사합니다.하지만 여기서는 효과가 없습니다. 대신 그것이 어디에 있든 관계없이 모든 HTML 주석과 일치합니다. – kakurala

0

String input = getJSPString(); 

final Pattern p = Pattern.compile(
    "\".*?(?<!\\\\)\"|" + // ignore string literals 
    "(?s)<%--.*?--%>|" + // ignore JSP comments 
    "<!--(.*?)-->");  // capture HTML comments in group #1 
Matcher m = p.matcher(input); 
StringBuffer sb = new StringBuffer(); 
while (m.find()) { 
    if (m.group(1) != null) { 
     m.appendReplacement(sb, "<%--$1--%>"); 
    } 
} 
m.appendTail(sb); 
String output = sb.toString(); 
당신은 당신의 소스가 HTML의 혼합이다 언급,이 변화 HTML 태그 도입 수있는 합병증을 제거
을 제공 할 수 있습니다.

원자 그룹과 \G 앵커를 추가하면
스택 오버플로의 위험이 거의 없습니다.

원시 정규식 교체 :

\G((?><(?:script(?:\s+(?:"[\S\s]*?"|'[\S\s]*?'|(?:(?!/>)[^>])*?)+)?\s*>[\S\s]*?</script\s*|(?:/?[\w:]+\s*/?)|(?:[\w:]+\s+(?:(?:(?:"[\S\s]*?")|(?:'[\S\s]*?'))|(?:[^>]*?))+\s*/?)|\?[\S\s]*?\?|(?:!(?:(?:DOCTYPE[\S\s]*?)|(?:\[CDATA\[[\S\s]*?\]\])|(?:ATTLIST[\S\s]*?)|(?:ENTITY[\S\s]*?)|(?:ELEMENT[\S\s]*?)))|%--[\S\s]*?--%)>|(?!<!--[\S\s]*?-->)[\S\s])*)<!--([\S\s]*?)--> 

연극, 정규식을 :

"\\G((?><(?:script(?:\\s+(?:\"[\\S\\s]*?\"|'[\\S\\s]*?'|(?:(?!/>)[^>])*?)+)?\\s*>[\\S\\s]*?</script\\s*|(?:/?[\\w:]+\\s*/?)|(?:[\\w:]+\\s+(?:(?:(?:\"[\\S\\s]*?\")|(?:'[\\S\\s]*?'))|(?:[^>]*?))+\\s*/?)|\\?[\\S\\s]*?\\?|(?:!(?:(?:DOCTYPE[\\S\\s]*?)|(?:\\[CDATA\\[[\\S\\s]*?\\]\\])|(?:ATTLIST[\\S\\s]*?)|(?:ENTITY[\\S\\s]*?)|(?:ELEMENT[\\S\\s]*?)))|%--[\\S\\s]*?--%)>|(?!<!--[\\S\\s]*?-->)[\\S\\s])*)<!--([\\S\\s]*?)-->" 

을 확장/포맷 :

\G       # G anchor 
(       # (1 start) 
     (?>       # Atomic group start 

      <        # Begin a Tag <, but not an html comment 
      (?: 
       script      # Script 
       (?: 
        \s+ 
        (?: 
          " [\S\s]*? " 
         | ' [\S\s]*? ' 
         | (?: 
           (?! />) 
           [^>] 
         )*? 
        )+ 
       )? 
       \s* > 
       [\S\s]*? </script \s* 
      |        # or, 
       (?:       # Non-attribute 
        /? 
        [\w:]+ 
        \s* 
        /? 
       ) 
      |        # or, 
       (?:       # Attribute 
        [\w:]+ 
        \s+ 
        (?: 
          (?: 
           (?: " [\S\s]*? ") 
          | (?: ' [\S\s]*? ') 
         ) 
         | (?: [^>]*?) 
        )+ 
        \s* 
        /? 
       ) 
      |        # or, 
       \?       # <? ?> form 
       [\S\s]*? 
       \? 
      |        # or, 
       (?:       # Misc <! > forms 
        ! 
        (?: 
          (?: 
           DOCTYPE 
           [\S\s]*? 
         ) 
         | (?: 
           \[CDATA\[ 
           [\S\s]*? 
           \]\] 
         ) 
         | (?: 
           ATTLIST 
           [\S\s]*? 
         ) 
         | (?: 
           ENTITY 
           [\S\s]*? 
         ) 
         | (?: 
           ELEMENT 
           [\S\s]*? 
         ) 
        ) 
       ) 
      |        # or, 
       %-- [\S\s]*? --%    # JSP comment 
      ) 
      >        # End a Tag > 

     |        # or, 
             # A character that does 
             # not begin a html comment 
      (?! <!-- [\S\s]*? -->) 
      [\S\s] 
    )*       # Atomic group end, 0 to many times 
)        # (1 end) 

<!-- 
([\S\s]*?)     # (2), Finally, the Html comment 
--> 
+0

스택 오버플로가 발생하게 된 원인은 무엇입니까? 재귀가 보이지 않습니다. – 4castle

+0

@ 4castle - 자바 정규 표현식 구현이 재귀적인 성격을 띠고 있다는 사실 이외에 다른 사실을 모르겠습니다. 나는 이것이 역 추적을 포함한다고 생각한다. Google은 모든 곳에서 사용합니다. – sln

+0

@sln, 귀하의 노력에 감사드립니다. 약간의 수정으로 4castle 버전의 코드를 시도했고 이것이 나의 요구 사항을 위해 노력하고 있습니다. – kakurala

0

당신이 patte을 사용할 수 있습니다 RN

(<!(--(?:[^-]|-(?!->))*?--)>)(?!((?!<%--)[\s\S])*?--%>) 

및 승 교체/<%$2%>
Demo

관련 문제