> 백엔드 개발 > PHP 튜토리얼 > javascript - 가장 안쪽 대괄호의 내용과 일치하는 정규식

javascript - 가장 안쪽 대괄호의 내용과 일치하는 정규식

WBOY
풀어 주다: 2016-08-04 09:19:46
원래의
1562명이 탐색했습니다.

이제 문자열이 있습니다:

<code>str1 = '(subject_id = "A" OR (status_id = "Open" AND (status_id = "C" OR level_id = "D")))'
</code>
로그인 후 복사
로그인 후 복사

또는

<code>str2 = '(subject_id = "A" OR subject_id = "Food" OR (subject_id = "C" OR (status_id = "Open" AND (status_id = "C" OR (level_id = "D" AND subject_id = "(Cat)")))))'
</code>
로그인 후 복사
로그인 후 복사

문자열에서 의 가장 안쪽 대괄호와 그 안의 내용을 일치시키기 위해 일반 규칙을 사용해야 합니다(따옴표 안의 대괄호는 일치하지 않음). 즉,

<code>str1 => (status_id = "C" OR level_id = "D")

str2 => (level_id = "D" AND subject_id = "(Cat)")
</code>
로그인 후 복사
로그인 후 복사

그렇다면 이 매우 복잡한 정규 표현식을 어떻게 작성해야 할까요?

정규 표현식을 구현할 수 없다면 JS에서는 어떻게 구현하나요?


추가로 str1에 대해 매칭을 만족시킬 수 있는 정규식을 찾았습니다.

<code>\([^()]+\)
</code>
로그인 후 복사
로그인 후 복사

그러나 str2의 경우 아직 해결책이 없습니다. 귀하의 답변을 기다리겠습니다!

답글 내용:

이제 문자열이 있습니다:

<code>str1 = '(subject_id = "A" OR (status_id = "Open" AND (status_id = "C" OR level_id = "D")))'
</code>
로그인 후 복사
로그인 후 복사

또는

<code>str2 = '(subject_id = "A" OR subject_id = "Food" OR (subject_id = "C" OR (status_id = "Open" AND (status_id = "C" OR (level_id = "D" AND subject_id = "(Cat)")))))'
</code>
로그인 후 복사
로그인 후 복사

문자열에서 의 가장 안쪽 대괄호와 그 안의 내용을 일치시키기 위해 일반 규칙을 사용해야 합니다(따옴표 안의 대괄호는 일치하지 않음). 즉,

<code>str1 => (status_id = "C" OR level_id = "D")

str2 => (level_id = "D" AND subject_id = "(Cat)")
</code>
로그인 후 복사
로그인 후 복사

그렇다면 이 매우 복잡한 정규 표현식을 어떻게 작성해야 할까요?

정규 표현식을 구현할 수 없다면 JS에서는 어떻게 구현하나요?


추가로 str1에 대해 매칭을 만족시킬 수 있는 정규식을 찾았습니다.

<code>\([^()]+\)
</code>
로그인 후 복사
로그인 후 복사

그러나 str2의 경우 아직 해결책이 없습니다. 귀하의 답변을 기다리겠습니다!

str2의 경우 이것을 찾았습니다

<code>\([^()]*\"[^"]*\"[^()]*\)</code>
로그인 후 복사

요구사항을 살펴보니 정규식 사용은 전혀 고려하지 않았습니다. 너무 복잡해 보였습니다. 그냥 전통적인 방법을 사용하겠습니다.
작업 우선 순위를 사용하면 됩니다. 즉, 스택 데이터 구조를 사용하여 내부 괄호의 내용을 가져옵니다. 기술 사항:

  1. 는 가장 안쪽 괄호

    와 일치합니다.
  2. 따옴표 안의 내용은 매칭기준으로 사용되지 않습니다

다음 아이디어를 바탕으로 알고리즘 설계를 시작합니다.

알고리즘은 일치시킬 하위 문자열의
startIndex를 계산한 다음 endIndex 메서드를 사용하여 하위 문자열 substring()을 얻습니다.

  • 문자가 일치하면 "("이 스택에 푸시됩니다. 의 첫 번째 이 일치하면 ")"이 스택에서 튀어나옵니다. stack, 즉 두 인덱스 사이의 하위 문자열이 대상 문자열입니다.

  • 과 일치하면
  • 일치를 중지하고 다음

    을 검색할 때까지 """ 검색을 계속하지 않습니다. "("""" "("

    제가 생각해낸 알고리즘입니다. 부족한 점이 있으면 자유롭게 추가해주세요.

//이 방법으로 시도해 보세요.

/(([^()]*?"[^"()]*([^"()] )[^( )]*?"[^()]*) )|([^()] )/
보충:


요구 분석 > 수요 지점별 솔루션 찾기 > 솔루션 통합 = 문제 해결

요구 사항 분석:

  1. 형식과 일치해야 합니다. ( a )

  2. 에 포함된 문자에는
  3. 을 사용하여 a을 나타내는 두 가지 가능성이 있습니다. a1 a2

      하나 이상의
    1. 형식을 포함하는 문자열,

      a1 b " c " b

      여기서
      1. ,

        또는 b을 포함하지 않는 문자열 "(입니다. )

        여기서
      2. 을 포함하지 않는 문자열

        c입니다. "

    2. 에는
    3. 또는

      a2(이 포함되지 않습니다. )

    역 파생:

2.2 =>

=

2.1.1 => 🎜>2.1 => a2= [^()]* =
=b[^()"]*1 =>
= c = [^"]*
a1 (b"c"b) 정규식: (b"c") b ([^()"]*"[^"]*") [^()"]*
확인: (a) (a1)|(a2) (([^()"]*"[^"]*") [^()"]*)|([^()]*)

그러면 다음과 같이 변경하세요.

가장 안쪽의 괄호와 그 안의 값을 가져온 후 값의 이전 숫자가 ""인지, 다음 숫자가 ""인지 확인합니다.
<code>/\(([^\(\)\"]*\"[^\"]*\")+[^\(\)\"]*\)|\([^\(\)]*\)/</code>
로그인 후 복사

존재하지 않는 경우 필수 답변입니다. 존재하는 경우 먼저 str에서 substr을 교체한 다음 일치시키고 마지막으로 다시 교체합니다.
<code class="javascript">var reg = /\(([^\(\)\"]*\"[^\"]*\")+[^\(\)\"]*\)|\([^\(\)]*\)/;

'(the (quick "brown" fox "jumps over, (the) lazy" dog ))'
    .match(reg)[0]
//"(quick "brown" fox "jumps over, (the) lazy" dog )"

'(the ("(quick)" brown fox "jumps (over, the)" lazy) dog )'
    .match(reg)[0];
//"("(quick)" brown fox "jumps (over, the)" lazy)"

'(the (quick brown fox (jumps "over", ((the) "lazy"))) dog )'
    .match(reg)[0];
//"(the)"</code>
로그인 후 복사
<code>str.replace(substr,"&&&")
str.replace(substr,"&&&").match(/\([^()]+\)/g)[0]
str.replace(substr,"&&&").match(/\([^()]+\)/g)[0].replace("&&&",substr)
</code>
로그인 후 복사

本题难点在需要对""进行递归统计,例如

<code>(level_id = "D AND subject_id = "(Cat)"")</code>
로그인 후 복사

(cat)是符合要求的.

<code>\([^()]*?\"((?:[^\"\"]|\"(?1)\")*+)\"[^()]*?\)|\([^()]*?\)
</code>
로그인 후 복사

真爱生命,远离正则,该正则可以满足你的要求,php能用(php支持递归)java及Python无法使用.

推荐一个思路,找到(的index,切字符串处理

手机发不出正则 黑线
楼主的【^()】里如果不匹配()则继续
把不匹配(的条件去掉,把贪婪的+改成*?即可

!代码

console.log('(subject_id = “A” OR (status_id = “Open” AND (status_id = “C” OR level_id = “D”)))'.match(/(1*)/))
希望对你有帮助
"javascript


  1. () ↩

用正则匹配会比较复杂,建议 把干扰串 "( 和 )" 替换掉,比如 "[, ]",再用简单的正则替换,之后再换回来。

正则用 Python 实现如下:

<code>import re

str1 = '(subject_id = "A" OR (status_id = "Open" AND (status_id = "C" OR level_id = "D")))'
str2 = '(subject_id = "A" OR subject_id = "Food" OR (subject_id = "C" OR (status_id = "Open" AND (status_id = "C" OR (level_id = "D" AND subject_id = "(Cat)")))))'

pat = re.compile(r"""(?<=[^"])
        \([^()]+?
        ("\(.+?\)")*
        \)
        (?=[^"])
        """, re.X)

print pat.search(str1).group(0)
print pat.search(str2).group(0)</code>
로그인 후 복사

输出为:

<code>(status_id = "C" OR level_id = "D")
(level_id = "D" AND subject_id = "(Cat)")
</code>
로그인 후 복사
관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿