Regexp (ruby)에서 선언 된 변수 (마스크) 수를 확인하는 방법은 무엇입니까?

이반 유로 프

임의의 양의 캡처 그룹이있는 정규 표현식이 있다고 가정 해 보겠습니다.

pattern = /(some)| ..a lot of masks combined.... |(other)/

그 그룹의 수를 결정하는 방법이 있습니까?

존 드보락

주어진 정규식과 일치하는 문자열을 항상 찾을 수 있다면 정규식과 일치시키는 것으로 충분 하고 일치 데이터 길이를 살펴보십시오 . 그러나 정규 표현식에 일치하는 문자열 있는지 확인하는 것은 np-hard [1] 입니다. 이것은 어떤 종류의 정규식을 얻을 것인지 미리 알고있는 경우에만 가능합니다.

Regexp클래스 에서 차선책으로 가장 좋은 방법 Regexp#source또는 Regexp#to_s입니다. 그러나 이렇게하면 정규식을 구문 분석해야합니다.

나는 미래에 대해 말할 수 없지만 Ruby 2.0 에서는 Regexp코어 클래스 에 더 좋은 방법이 없습니다 .

이스케이프 처리되지 않은 백 슬래시가 앞에 오는 경우 왼쪽 괄호는 리터럴 왼쪽 괄호를 나타냅니다. 이스케이프 처리되지 않은 백 슬래시가 앞에 나오지 않는 한 백 슬래시는 이스케이프 처리되지 않습니다. 따라서 문자는 홀수의 백 슬래시가 앞에 오는 경우 이스케이프됩니다.

이스케이프 처리되지 않은 왼쪽 괄호는 물음표가 뒤에 나오지 않는 경우 캡처 그룹을 나타냅니다. 물음표와 함께, 다양한 것을 의미 할 수 있습니다 (?'name')(?<name>)명명 된 캡처 그룹을 나타낸다. 명명 된 캡처 링 그룹과 명명되지 않은 캡처 링 그룹은 동일한 정규식에서 공존 할 수 없지만 [2] . (?:)캡처하지 않는 그룹을 나타냅니다. 이것은의 특별한 경우입니다 (?flags-flags:). (?>)원자 그룹을 나타냅니다. (?=), (?!), (?<=)(?<!)나타내고 lookaround. (?#)주석을 나타냅니다.

Ruby regexp 엔진은 regexe의 주석을 지원합니다. 기본 정규식에서 고려하는 것은 매우 어려울 것입니다. 우리가 정말로 이것을 지원하고 싶다면 그것들을 제거하려고 시도 할 수 있지만, 정규 표현식이 캡처 할 수없는 방식으로 확장 모드 (및 라인 주석)를 켜고 끌 수있는 인라인 플래그의 가능성으로 인해 완전히 지원할 수 있습니다. 계속해서 정규식 주석에서 이스케이프 처리되지 않은 괄호를 지원하지 않을 것입니다 [3] .

우리는 다음을 계산합니다.

  • 왼쪽 괄호의 수 \(
  • 백 슬래시로 이스케이프되지 않는 것 (?<!(?<!\\)(?:\\\\)*\\)(읽기 : 앞에 또 다른 백 슬래시가없는 홀수의 백 슬래시가 선행되지 않음)
  • 뒤에 물음표가없는 (?!\?)

Ruby는 제한없는 lookbehind를 지원하지 않지만 소스를 먼저 뒤집 으면 첫 번째 주장을 약간 다시 작성할 수 있습니다 (?!(?:\\\\)*(?!\\)).. 두 번째 주장은 lookbehind : (?<!\?).

전체 솔루션

def count_groups(regexp)
  # named capture support:
  # named_count = regexp.named_captures.count 
  # return named_count if named_count > 0

  # main: 
  test = /(?!<\?)\((?!(?:\\\\)*(?!\\))/
  regexp.source.scan(test).count
end

[1] : 만족도 문제를 다음과 같이 변환하여 NP 경도를 나타낼 수 있습니다.

  • AND : xy( x어설 션이어야 함)
  • 또는: x|y
  • 아니: (?!x)
  • 원자 : (?=1), (?=.1), (?=..1), ..., (?!1), (?!.1)...

예 (XOR) : /^(?:(?=1)(?!.1)|(?!1)(?=.1))..$/

이는 다항식 시간에 테스트 할 수있는 모든 정규식 클래스에 대한 NP 완전성으로 확장됩니다. 여기에는 중첩 된 반복 (또는 반복 또는 반복에 대한 반복 된 역 참조)이없고 선택적 일치의 중첩 된 중첩 깊이가있는 모든 정규식이 포함됩니다.

[2] :를 /((?<name>..)..)../.match('abcdef').to_a반환합니다 ['abcdef', 'ab']. 이는 명명 된 캡처 링 그룹이있는 경우 명명되지 않은 캡처 링 그룹이 무시됨을 나타냅니다. Ruby 1.9.3에서 테스트 됨

[3] : 인라인 주석은로 시작 (?#하고로 끝납니다 ). 이스케이프 처리되지 않은 오른쪽 괄호는 포함 할 수 없지만 이스케이프 처리되지 않은 왼쪽 괄호는 포함 할 수 있습니다. 이것들은 쉽게 벗겨 질 수 있고 (우리가 "이스케이프되지 않은"정규식을 어디에나 뿌려야하더라도) 덜 악하지만, 이스케이프되지 않은 왼쪽 괄호를 포함 할 가능성도 적습니다.

줄 주석은 #개행으로 시작 하고 끝납니다. 확장 모드에서는 주석으로 만 처리됩니다 . 확장 모드 외부에서는 리터럴 #및 개행 문자 일치합니다 . 이스케이프를 다시 고려해야하더라도 여전히 쉽습니다 . 정규식에 확장 플래그 세트가 있는지 확인하는 것은 그리 어렵지 않지만 플래그 수정 자 그룹은 완전히 다른 짐승입니다.

Ruby의 멋진 재귀 정규식을 사용하더라도 확장 모드를 수정하는 이전에 열린 그룹이 이미 닫혔는지 확인하는 것만으로도 매우 불쾌한 정규식을 생성 할 수 있습니다 (하나씩 교체하고 주석을 건너 뛸 필요가없는 경우에도). 탈출). (보간을 사용해도) 예쁘지 않을 것이고 빠르지도 않을 것입니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

xaml 디자이너 페이지에 선언 된 변수에 액세스하는 방법은 무엇입니까?

분류에서Dev

포함 된 페이지에서 선언 된 변수를 사용하는 방법은 무엇입니까?

분류에서Dev

선언 된 곳과 다른 파일에서 변수를 편집하는 방법은 무엇입니까?

분류에서Dev

파일 내에서 선언 된 변수를 다른 파일로 호출하는 방법은 무엇입니까?

분류에서Dev

/ etc / profie에 선언 된 환경 변수를 monit을 통해 실행되는 스크립트에 사용하는 방법은 무엇입니까?

분류에서Dev

언어 C. 이전에 선언 된 변수의 lvalue 식별자를 얻는 방법은 무엇입니까?

분류에서Dev

서브 루틴에서 크기가 수정 된 배열을 선언하는 방법은 무엇입니까?

분류에서Dev

재구성 된 텍스트 / 스핑크스로 문서화 할 때 선언에 매개 변수 유형을 포함하는 방법은 무엇입니까?

분류에서Dev

둘 이상의 소스 파일에서 헤더 파일에 선언 된 구조체 변수를 포함하는 방법은 무엇입니까?

분류에서Dev

둘 이상의 소스 파일에서 헤더 파일에 선언 된 구조체 변수를 포함하는 방법은 무엇입니까?

분류에서Dev

SELECT 내에서 변수를 선언하는 방법은 무엇입니까?

분류에서Dev

if 조건 내에서 변수를 선언하는 방법은 무엇입니까?

분류에서Dev

Perl에서 변수 선언을 래퍼 스크립트로 추출하는 방법은 무엇입니까?

분류에서Dev

정수형 템플릿 함수에서 snprinf 마스크를 선택하는 방법은 무엇입니까?

분류에서Dev

값이 JS에서 변수로 구성된 객체 일 때 변수를 선언하는 방법은 무엇입니까?

분류에서Dev

백본, 뷰 내에서 선언 된 함수가 해당 뷰의 DOM 요소에만 영향을 미치는지 확인하는 방법은 무엇입니까?

분류에서Dev

변수에 저장된 jQuery 선택기를 확장하는 방법은 무엇입니까?

분류에서Dev

변수가 함수 외부에서 선언 된 경우 함수 내부에서 변수 값을 조작하는 방법은 무엇입니까?

분류에서Dev

자바 스크립트에서 전역 변수를 올바른 방법으로 선언하는 방법은 무엇입니까?

분류에서Dev

Tcl regexp : 변수에 숫자가 포함되어 있는지 확인하는 방법은 무엇입니까?

분류에서Dev

WPF DataGrid : ComboBox 선택이 변경된 행의 인덱스를 확인하는 방법은 무엇입니까?

분류에서Dev

PHP 클래스에서 개인 함수로 변수 존재를 확인하는 방법은 무엇입니까?

분류에서Dev

Ruby 다른 메서드에서 인스턴스 변수를 수정하는 방법은 무엇입니까?

분류에서Dev

입력 문자열에 언급 된 변수를 변경하는 방법은 무엇입니까?

분류에서Dev

PHP에서 Java 스크립트로로드 된 URL에서 변수를 얻는 방법은 무엇입니까?

분류에서Dev

Ruby의 시스템에서 .zshrc에 정의 된 함수를 실행하는 방법은 무엇입니까?

분류에서Dev

TCL에서 상수를 선언하는 방법은 무엇입니까?

분류에서Dev

flutter (dart)에서 비동기 함수를 변수로 선언하는 방법은 무엇입니까?

분류에서Dev

'C'의 함수 내에서 전역 변수를 선언하는 방법은 무엇입니까?

Related 관련 기사

  1. 1

    xaml 디자이너 페이지에 선언 된 변수에 액세스하는 방법은 무엇입니까?

  2. 2

    포함 된 페이지에서 선언 된 변수를 사용하는 방법은 무엇입니까?

  3. 3

    선언 된 곳과 다른 파일에서 변수를 편집하는 방법은 무엇입니까?

  4. 4

    파일 내에서 선언 된 변수를 다른 파일로 호출하는 방법은 무엇입니까?

  5. 5

    / etc / profie에 선언 된 환경 변수를 monit을 통해 실행되는 스크립트에 사용하는 방법은 무엇입니까?

  6. 6

    언어 C. 이전에 선언 된 변수의 lvalue 식별자를 얻는 방법은 무엇입니까?

  7. 7

    서브 루틴에서 크기가 수정 된 배열을 선언하는 방법은 무엇입니까?

  8. 8

    재구성 된 텍스트 / 스핑크스로 문서화 할 때 선언에 매개 변수 유형을 포함하는 방법은 무엇입니까?

  9. 9

    둘 이상의 소스 파일에서 헤더 파일에 선언 된 구조체 변수를 포함하는 방법은 무엇입니까?

  10. 10

    둘 이상의 소스 파일에서 헤더 파일에 선언 된 구조체 변수를 포함하는 방법은 무엇입니까?

  11. 11

    SELECT 내에서 변수를 선언하는 방법은 무엇입니까?

  12. 12

    if 조건 내에서 변수를 선언하는 방법은 무엇입니까?

  13. 13

    Perl에서 변수 선언을 래퍼 스크립트로 추출하는 방법은 무엇입니까?

  14. 14

    정수형 템플릿 함수에서 snprinf 마스크를 선택하는 방법은 무엇입니까?

  15. 15

    값이 JS에서 변수로 구성된 객체 일 때 변수를 선언하는 방법은 무엇입니까?

  16. 16

    백본, 뷰 내에서 선언 된 함수가 해당 뷰의 DOM 요소에만 영향을 미치는지 확인하는 방법은 무엇입니까?

  17. 17

    변수에 저장된 jQuery 선택기를 확장하는 방법은 무엇입니까?

  18. 18

    변수가 함수 외부에서 선언 된 경우 함수 내부에서 변수 값을 조작하는 방법은 무엇입니까?

  19. 19

    자바 스크립트에서 전역 변수를 올바른 방법으로 선언하는 방법은 무엇입니까?

  20. 20

    Tcl regexp : 변수에 숫자가 포함되어 있는지 확인하는 방법은 무엇입니까?

  21. 21

    WPF DataGrid : ComboBox 선택이 변경된 행의 인덱스를 확인하는 방법은 무엇입니까?

  22. 22

    PHP 클래스에서 개인 함수로 변수 존재를 확인하는 방법은 무엇입니까?

  23. 23

    Ruby 다른 메서드에서 인스턴스 변수를 수정하는 방법은 무엇입니까?

  24. 24

    입력 문자열에 언급 된 변수를 변경하는 방법은 무엇입니까?

  25. 25

    PHP에서 Java 스크립트로로드 된 URL에서 변수를 얻는 방법은 무엇입니까?

  26. 26

    Ruby의 시스템에서 .zshrc에 정의 된 함수를 실행하는 방법은 무엇입니까?

  27. 27

    TCL에서 상수를 선언하는 방법은 무엇입니까?

  28. 28

    flutter (dart)에서 비동기 함수를 변수로 선언하는 방법은 무엇입니까?

  29. 29

    'C'의 함수 내에서 전역 변수를 선언하는 방법은 무엇입니까?

뜨겁다태그

보관