如何在Golang中实现正则表达式的不匹配?

huangapple go评论88阅读模式
英文:

how to realize mismatch of regexp in golang?

问题

这是一个多项选择题的示例。我想要在以下的 Golang 代码中获取中文文本,例如“英国、法国”、“加拿大、墨西哥”、“葡萄牙、加拿大”、“墨西哥、德国”,但是它没有起作用。

package main

import (
	"fmt"
	"regexp"
	"testing"
)

func TestRegex(t *testing.T) {
	text := `( B )38.目前,亚马逊美国站后台,除了有美国站点外,还有(    )站点。
A.英国、法国B.加拿大、墨西哥
C.葡萄牙、加拿大D.墨西哥、德国
`

	fmt.Printf("%q\n", regexp.MustCompile(`[A-E]\.(\S+)?`).FindAllStringSubmatch(text, -1))
	fmt.Printf("%q\n", regexp.MustCompile(`[A-E]\.`).Split(text, -1))
}

文本:

( B )38.目前,亚马逊美国站后台,除了有美国站点外,还有(    )站点。
A.英国、法国B.加拿大、墨西哥
C.葡萄牙、加拿大D.墨西哥、德国

模式:[A-E]\.(\S+)?

实际结果:[[“A.英国、法国B.加拿大、墨西哥” “英国、法国B.加拿大、墨西哥”] [“C.葡萄牙、加拿大D.墨西哥、德国” “葡萄牙、加拿大D.墨西哥、德国”]]

期望结果:[[“A.英国、法国” “英国、法国”] [“B.加拿大、墨西哥” “加拿大、墨西哥”] [“C.葡萄牙、加拿大” “葡萄牙、加拿大”] [“D.墨西哥、德国” “墨西哥、德国”]]

我认为这可能是一个贪婪模式的问题。因为在我的代码中,它将选项 A 和选项 B 直接读取为一个选项。

英文:

This is a multiple choice question example. I want to get the chinese text like "英国、法国", "加拿大、墨西哥", "葡萄牙、加拿大", "墨西哥、德国" in the content of following code in golang, but it does not work.

package main

import (
	"fmt"
	"regexp"
	"testing"
)

func TestRegex(t *testing.T) {
	text := `( B )38.目前,亚马逊美国站后台,除了有美国站点外,还有(    )站点。
A.英国、法国B.加拿大、墨西哥
C.葡萄牙、加拿大D.墨西哥、德国
`

	fmt.Printf("%q\n", regexp.MustCompile(`[A-E]\.(\S+)?`).FindAllStringSubmatch(text, -1))
	fmt.Printf("%q\n", regexp.MustCompile(`[A-E]\.`).Split(text, -1))
}

text:

( B )38.目前,亚马逊美国站后台,除了有美国站点外,还有(    )站点。
A.英国、法国B.加拿大、墨西哥
C.葡萄牙、加拿大D.墨西哥、德国

pattern: [A-E]\.(\S+)?

Actual result: [["A.英国、法国B.加拿大、墨西哥" "英国、法国B.加拿大、墨西哥"] ["C.葡萄牙、加拿大D.墨西哥、德国" "葡萄牙、加拿大D.墨西哥、德国"]].

Expect result: [["A.英国、法国" "英国、法国"] ["B.加拿大、墨西哥" "加拿大、墨西哥"] ["C.葡萄牙、加拿大" "葡萄牙、加拿大"] ["D.墨西哥、德国" "墨西哥、德国"]]

I think it might be a greedy mode problem. Because in my code, it reads option A and option B as one option directly.

答案1

得分: 1

非贪婪匹配无法解决这个问题,你需要使用正向先行断言,而re2不支持这个功能。

作为一种解决方法,可以通过在标签上进行搜索并手动提取之间的文本。

re := regexp.MustCompile(`[A-E]\.`)
res := re.FindAllStringIndex(text, -1)
results := make([][]string, len(res))
for i, m := range res {
    if i < len(res)-1 {
        results[i] = []string{text[m[0]:m[1]], text[m[1]:res[i+1][0]]}
    } else {
        results[i] = []string{text[m[0]:m[1]], text[m[1]:]}
    }
}

fmt.Printf("%q\n", results)

应该打印出:

[["A." "英国、法国"] ["B." "加拿大、墨西哥\n"] ["C." "葡萄牙、加拿大"] ["D." "墨西哥、德国\n"]]
英文:

Non-greedy matching won't solve this, you need positive lookahead, which re2 doesn't support.

As a workaround can just search on the labels and extract the text in between manually.

re := regexp.MustCompile(`[A-E]\.`)
res := re.FindAllStringIndex(text, -1)
results := make([][]string, len(res))
for i, m := range res {
	if i &lt; len(res)-1 {
		results[i] = []string{text[m[0]:m[1]], text[m[1]:res[i+1][0]]}
	} else {
		results[i] = []string{text[m[0]:m[1]], text[m[1]:]}
	}
}

fmt.Printf(&quot;%q\n&quot;, results)

Should print

[[&quot;A.&quot; &quot;英国、法国&quot;] [&quot;B.&quot; &quot;加拿大、墨西哥\n&quot;] [&quot;C.&quot; &quot;葡萄牙、加拿大&quot;] [&quot;D.&quot; &quot;墨西哥、德国\n&quot;]]

huangapple
  • 本文由 发表于 2021年12月6日 21:32:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/70246330.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定