2017-05-07 3 views
0

Python과 다양한 언어에서 완벽하게 작동하지만 정규식 (예 : 엔진)에 대한 구현에 필요한 하위 일치 항목을 캡처하지 못하는 정규식 패턴이 있습니다. 어떤 것은 JavaScript와 거의 동일하다). 다음과 같이 문제의 패턴은 다음과 같이Submatch 문제를 해결하기 위해 VBScript/Javascript Regex의 차이점 이해

"Sincerely,[\s\n]+([\w\.]+)\s+(\w+)\s+(.+)[\s\n]+(\d+\s.+)[\s\n]+(.+)" 

예 테스트 케이스는 다음과 같습니다

email received 3/30/17: 

Dear Sir, 

Hello 

Sincerely, 

Mr. Robert Thomas 
1104 Madison Avenue 
New York, NY 10021 


email received 3/30/17: 

Dear Sir, 

Hello 

Sincerely, 

Ms. Angela Carraway 
402 Arlington Drive 
Concord, MA 01742 

목적은 변수 키워드 다음에이 예 일치 만점에 5 개 하위 그룹을 추출하는 글로벌 정규식입니다 여기는 "근실하게"입니다. 소그룹은 Ms. (첫 번째 하위 그룹), Angela (두 번째 하위 그룹), Carraway (세 번째 하위 그룹), 402 Arlington Drive (네 번째 하위 그룹), Concord, MA 01742 (다섯 번째 하위 그룹)이어야합니다. 파이썬에서는 Regex 테스터에서 5 개의 그룹을 완벽하게 일치 시키지만 VBScript (JavaScript 엔진)의 경우 전체 문자열을 일치로 일치하지만 하위 그룹은 전혀 갖지 않습니다. 따라서 Excel VBA 매크로에서 하위 일치 항목을 호출하여 셀에 쓰면 모든 텍스트가 뒤죽박죽이되어 몇 개의 셀로 들어갑니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 하위 그룹을 캡처하지 못하게하는 일부 문자가 누락 되었습니까? 그렇다면이 두 엔진 사이의 중요한 차이점은 무엇입니까? 그래서 나는 이것을 피할 수 있습니다. 어떻게이 테스트 케이스에서이 패턴을 고칠 수 있습니까? 나는 온라인상의 차이점에 대해 읽으려고 노력했지만, 모든 것은 내가 가지고있는 이슈를 일으키는 작은 차이 만있는 것 같다. 내가 차이점/문제를 분리 할 수 ​​없기 때문에 어떤 도움이라도 대단히 감사하겠습니다. 고맙습니다!

편집 : 이것은 결과의 사진이

Sub regex() 
    Dim docxinput As String 
    Dim keyword As Variant 
    Dim patterninput As Variant 
    Dim pattern As String 
    Dim regex As New RegExp 

    docxinput = Application.GetOpenFilename(Title:="Step #1: Enter Word Document Input File Name") 
     Dim wrdApp As Word.Application 
     Dim wrdDoc As Word.Document 
     Dim strInput As String 

     Set wrdApp = CreateObject("Word.Application") 
     wrdApp.Visible = False 

     Set wrdDoc = wrdApp.Documents.Open(docxinput) 
     strInput = wrdDoc.Range.Text 

     Debug.Print (strInput) 
     wrdDoc.Close 0 
     Set wrdDoc = Nothing 
     wrdApp.Quit 
     Set wrdApp = Nothing 

    pattern = "Sincerely,[\s\n]+([\w\.]+)\s+(\w+)\s+(.+)[\s\n]+(\d+\s.+)[\s\n]+(.+)" 

    Dim objMatches As MatchCollection 

    With regex 
     .Global = True 
     .MultiLine = True 
     .IgnoreCase = False 
     .pattern = pattern 
    End With 

    Set objMatches = regex.Execute(strInput) 
    Dim row As Variant 

    Dim SubMatches As Variant 
    row = 2 
    For Each SubMatches In objMatches 
     Cells(row, 1).Value = objMatches(0).SubMatches(0) 
     Cells(row, 2).Value = objMatches(0).SubMatches(1) 
     Cells(row, 3).Value = objMatches(0).SubMatches(2) 
     Cells(row, 4).Value = objMatches(0).SubMatches(3) 
     Cells(row, 5).Value = objMatches(0).SubMatches(4) 
     row = row + 1 
    Next 
End Sub 

: 다음은 정규식을 사용 VBA 코드입니다. 보시다시피 첫 번째 두 개의 하위 그룹이 작동하지만 정규 표현식 (또는 최소한 생각하면)은 그룹화 오류로 실행되고 다른 내용의 거의 대부분이 다음 열로 덤프됩니다. 그런 다음 오류가있는 네 번째 열로 이동합니다. 이것은 코드 반복 또는 정규식 자체에 문제가 있습니까? 나는 코드 문제를 해결하기 위해 시도하고 정규식 이외의 텍스트를 올바르게 올릴 수없는 이유를 찾을 수 없습니다. 이견있는 사람?

사진 : Screenshot of VBA Regex Issue

+0

정규식을 실행하고 서브 쿼리를 검색하는 VBA 코드를 게시 할 수 있습니까? –

+0

@RichHolton VBA를 실행할 때 얻은 결과 그림과 함께 코드 및 추가 설명문을 보여주는 원본 게시물을 편집했습니다. 이견있는 사람? –

+0

텍스트에 \ n이 아닌 다른 줄이있는 것으로 의심되어 세 번째 그룹 (. *)이 너무 많이 캡처 한 다음 나머지를 던집니다. 확인해 볼 수 있니? –

답변

1

당신의 regex 문제없이 VBA으로 실행해야는 ... 는 vba 여기 how-to-use-regular-expressions-regex-in-microsoft-excel-both-in-cell-and-loops 살펴에서 원하는 그룹을 얻으려면

(IT here 테스트).

편집 : 다음과 같은 입력에 대한 : 셀 A1

및 VBA 코드 안에 넣어

email received 3/30/17: 

Dear Sir, 

Hello 

Sincerely, 

Mr. Robert Thomas 
1104 Madison Avenue 
New York, NY 10021 


email received 3/30/17: 

Dear Sir, 

Hello 

Sincerely, 

Ms. Angela Carraway 
402 Arlington Drive 
Concord, MA 01742 

: 나는 변경해야한다고

(주 당신의 for each 루프 - 여러 일치 항목에서 작동 할 수 있도록)

Sub myregex() 
    Dim keyword As Variant 
    Dim patterninput As Variant 
    Dim pattern As String 
    Dim regex As New RegExp 

    Set Myrange = ActiveSheet.Range("A1:A1") 
    For Each C In Myrange 
    strInput = C.Value 
    strPattern = "Sincerely,[\s\n]+([\w\.]+)\s+(\w+)\s+(.+)[\s\n]+(\d+\s.+)[\s\n]+(.+)" 

    With regex 
       .Global = True 
       .MultiLine = True 
       .IgnoreCase = False 
       .pattern = strPattern 
      End With 
      If regex.Test(strInput) Then 
       Set objMatches = regex.Execute(strInput) 
       row = 2 
       For Each SubMatches In objMatches 
       Cells(row, 1).Value = objMatches(row - 2).SubMatches(0) 
       Cells(row, 2).Value = objMatches(row - 2).SubMatches(1) 
       Cells(row, 3).Value = objMatches(row - 2).SubMatches(2) 
       Cells(row, 4).Value = objMatches(row - 2).SubMatches(3) 
       Cells(row, 5).Value = objMatches(row - 2).SubMatches(4) 
       row = row + 1 
       Next 
      Else 
       C.Offset(0, 1) = "(Not matched)" 
      End If 

    Next 
End Sub 

691,363,210 나는 다음과 같은 결과를 얻었다 :

 A  B  C   D     E 
    2 Mr. Robert Thomas  1104 Madison Avenue New York, NY 10021 
    3 Ms. Angela Carraway 402 Arlington Drive Concord, MA 01742 

결론 : 예상대로 모든 것이 작동합니다.

+0

나는 그 테스터도 시험해 보았는데 모든 것을 하나의 하위 그룹과 일치하지 않는 것으로 산출했다. 그게 정상인가요? 그것이 의미가있는 경우 그 그룹 내에 5 개의 캡쳐 된 하위 그룹이 필요합니다. 나는 또한 원래의 게시물을 편집하여 정규식 패턴이라고 생각하는 것과 관련된 문제에 대해 자세히 설명합니다. –

+0

@ J.Squillaro 그래서, 테스터 (나의 첫 번째 링크)에서'split lists' 탭을 선택하면 거기에 5 개의 그룹이 보일 것입니다. vba에서 각 그룹을 얻는 방법은 두 번째 링크를보십시오. , 감사 안녕하세요에게, 나는 워드 문서 만 친애하는 각하'하나의 문자열로 엑셀 셀을 사용하지 않은 - – Plirkee

+0

은 J.Squillaro @ 당신의'vba' 스크립트는 잘 내 엑셀 (일부 adaptions 후 과정에 나를 위해 일한 미스터 로버트 토마스 1104 매디슨 애비뉴 뉴욕, 뉴욕 10021은 - 그러나 정규 표현식 부분 - 엑셀 2010, VB는 스크립트 정규 표현식 5.5) – Plirkee

관련 문제