2012-11-11 43 views
6

Tôi đang cố gắng tìm bắt đầu của một nhóm chụp được đặt tên trong chuỗi để tạo một trình phân tích cú pháp đơn giản (xem related question). Để thực hiện việc này, hàm extract sẽ ghi nhớ ký tự cuối cùng cho các ký tự trong biến số last4. Nếu 4 ký tự cuối cùng là bằng "(P <?" Nó là sự khởi đầu của một nhóm chụp:So sánh các chuỗi trong Go

package main 

import "fmt" 

const sample string = `/(?P<country>m((a|b).+)(x|y)n)/(?P<city>.+)` 

func main() { 
    extract(sample) 
} 

func extract(regex string) { 
    last4 := new([4]int32) 
    for _, c := range regex { 
     last4[0], last4[1], last4[2], last4[3] = last4[1], last4[2], last4[3], c 
     last4String := fmt.Sprintf("%c%c%c%c\n", last4[0], last4[1], last4[2], last4[3]) 
     if last4String == "(?P<" { 
      fmt.Print("start of capturing group") 
     } 
    } 
} 

http://play.golang.org/p/pqA-wCuvux

Nhưng điều này in đang không có gì last4String == "(?P<" không bao giờ là sự thật, mặc dù substrin này xuất hiện trong đầu ra nếu tôi in last4String bên trong vòng lặp. Làm thế nào để so sánh chuỗi trong Go rồi?

Và đó là một cách thanh lịch hơn để chuyển đổi một mảng int32 thành một chuỗi hơn fmt.Sprintf("%c%c%c%c\n", last4[0], last4[1], last4[2], last4[3])?

Bất cứ điều gì khác có thể tốt hơn? Mã của tôi có vẻ hơi không phù hợp với tôi.

Trả lời

3

Nếu không phải là tự học hoặc tương tự, bạn có thể muốn sử dụng RE parser hiện có trong thư viện chuẩn và sau đó "đi bộ" AST để làm bất cứ điều gì bắt buộc.

func Parse(s string, flags Flags) (*Regexp, error) 

Parse phân tích một chuỗi biểu thức chính quy s, điều khiển bởi Flags quy định, và trả về một cây phân tích cú pháp biểu hiện thường xuyên. Cú pháp được mô tả trong chú thích cấp cao nhất của cho gói regexp.

Thậm chí còn có helper cho công việc của bạn.

EDIT1: Mã của bạn sửa chữa:

package main 

import "fmt" 

const sample string = `/(?P<country>m((a|b).+)(x|y)n)/(?P<city>.+)` 

func main() { 
     extract(sample) 
} 

func extract(regex string) { 
     var last4 [4]int32 
     for _, c := range regex { 
       last4[0], last4[1], last4[2], last4[3] = last4[1], last4[2], last4[3], c 
       last4String := fmt.Sprintf("%c%c%c%c", last4[0], last4[1], last4[2], last4[3]) 
       if last4String == "(?P<" { 
        fmt.Println("start of capturing group") 
       } 
     } 
} 

(Cũng here)

EDIT2: viết lại code của bạn:

package main 

import (
     "fmt" 
     "strings" 
) 

const sample string = `/(?P<country>m((a|b).+)(x|y)n)/(?P<city>.+)` 

func main() { 
     extract(sample) 
} 

func extract(regex string) { 
     start := 0 
     for { 
       i := strings.Index(regex[start:], "(?P<") 
       if i < 0 { 
         break 
       } 

       fmt.Printf("start of capturing group @ %d\n", start+i) 
       start += i + 1 
     } 
} 

(Cũng here)