Regex 无法识别单词中的撇号以替换字符串

Regex 无法识别单词中的撇号以替换字符串,regex,go,regex-group,Regex,Go,Regex Group,我在用regexp替换单词“you's”时遇到问题 所有其他的词都在正确地变化,只有“你是”这个词。 我认为它不是在撇号后面 我必须把“你”换成“我”,把“你”换成“我”。 它会将“you”改为“I”,但“you's”会变成“I's”,因为它不会超过撇号,而且它认为出于某种原因,这是单词的结尾。我得设法避开撇号 请参阅下面的代码 package main import ( "fmt" "math/rand" "regexp" "strings" "tim

我在用regexp替换单词“you's”时遇到问题

所有其他的词都在正确地变化,只有“你是”这个词。 我认为它不是在撇号后面

我必须把“你”换成“我”,把“你”换成“我”。 它会将“you”改为“I”,但“you's”会变成“I's”,因为它不会超过撇号,而且它认为出于某种原因,这是单词的结尾。我得设法避开撇号

请参阅下面的代码

package main

import (
    "fmt"
    "math/rand"
    "regexp"
    "strings"
    "time"
)

//Function ElizaResponse to take in and return a string
func ElizaResponse(str string) string {

    //  replace := "How do you know you are"

    /*Regex MatchString function with isolation of the word "father"
    *with a boundry ignore case regex command.
     */
    if matched, _ := regexp.MatchString(`(?i)\bfather\b`, str);
    //Condition to replace the original string if it has the word "father"
    matched {
        return "Why don’t you tell me more about your father?"
    }
    r1 := regexp.MustCompile(`(?i)\bI'?\s*a?m\b`)

    //Match the words "I am" and capture for replacement
    matched := r1.MatchString(str)

    //condition if "I am" is matched
    if matched {

        capturedString := r1.ReplaceAllString(str, "$1")
        boundaries := regexp.MustCompile(`\b`)
        tokens := boundaries.Split(capturedString, -1)

        // List the reflections.
        reflections := [][]string{
            {`I`, `you`},
            {`you're`, `I'm`},
            {`your`, `my`},
            {`me`, `you`},
            {`you`, `I`},
            {`my`, `your`},
        }

        // Loop through each token, reflecting it if there's a match.
        for i, token := range tokens {
            for _, reflection := range reflections {
                if matched, _ := regexp.MatchString(reflection[0], token); matched {
                    tokens[i] = reflection[1]
                    break
                }
            }
        }

        // Put the tokens back together.
        return strings.Join(tokens, ``)

    }

    //Get random number from the length of the array of random struct
    //an array of strings for the random response
    response := []string{"I’m not sure what you’re trying to say. Could you explain it to me?",
        "How does that make you feel?",
        "Why do you say that?"}
    //Return a random index of the array
    return response[rand.Intn(len(response))]

}

func main() {
    rand.Seed(time.Now().UTC().UnixNano())

    fmt.Println("Im supposed to just take what you're saying at face value?")
    fmt.Println(ElizaResponse("Im supposed to just take what you're saying at face value?"))


}

请注意,撇号字符创建了一个单词边界,因此在正则表达式中使用
\b
可能会让您大吃一惊。也就是说,字符串
“I'm”
有四个单词边界,每个字符前后各一个

┏━┳━┳━┓
┃我┃'┃M┃
┗━┻━┻━┛
│ │ │ └─ 行尾创建单词边界
│ │ └─── 标点符号后,字符创建单词边界
│ └───── 在标点符号字符创建单词边界之前
└─────── 行首创建一个单词边界
无法更改单词边界元字符的行为,因此最好将包含带标点的完整单词的正则表达式映射到所需的替换项,例如:

type Replacement struct {
  rgx *regexp.Regexp
  rpl string
}

replacements := []Replacement{
  {regexp.MustCompile("\\bI\\b"), "you"},
  {regexp.MustCompile("\\byou're\\b"), "I'm"},
  // etc...
}
还要注意,其中一个示例包含UTF-8“右单引号”(U+2019,0xe28099),不要与UTF-8/ASCII撇号(U+0027,0x27)混淆


请注意,撇号字符创建了一个单词边界,因此在正则表达式中使用
\b
可能会让您大吃一惊。也就是说,字符串
“I'm”
有四个单词边界,每个字符前后各一个

┏━┳━┳━┓
┃我┃'┃M┃
┗━┻━┻━┛
│ │ │ └─ 行尾创建单词边界
│ │ └─── 标点符号后,字符创建单词边界
│ └───── 在标点符号字符创建单词边界之前
└─────── 行首创建一个单词边界
无法更改单词边界元字符的行为,因此最好将包含带标点的完整单词的正则表达式映射到所需的替换项,例如:

type Replacement struct {
  rgx *regexp.Regexp
  rpl string
}

replacements := []Replacement{
  {regexp.MustCompile("\\bI\\b"), "you"},
  {regexp.MustCompile("\\byou're\\b"), "I'm"},
  // etc...
}
还要注意,其中一个示例包含UTF-8“右单引号”(U+2019,0xe28099),不要与UTF-8/ASCII撇号(U+0027,0x27)混淆


我发现我只需要更改这两行代码

boundaries := regexp.MustCompile(`(\b[^\w']|$)`)
return strings.Join(tokens, ` `)
它会阻止拆分函数在“字符”处拆分。
然后,令牌的返回需要一个空格来输出字符串,否则它将是一个连续字符串。

我发现我只需要更改这两行代码

boundaries := regexp.MustCompile(`(\b[^\w']|$)`)
return strings.Join(tokens, ` `)
它会阻止拆分函数在“字符”处拆分。
然后,令牌的返回需要一个空间来输出字符串,否则它将是一个连续字符串。

这里要实现的是用特定替换替换特定字符串。使用字符串键和值的映射更容易实现这一点,其中每个唯一键都是要搜索的文本短语,值是要替换的文本

以下是定义反射的方式:

接下来,您需要按长度降序获取密钥(如下所示):

然后在函数中:

var keys []string
for key, _ := range reflections {
    keys = append(keys, key)
}
sort.Sort(ByLenDesc(keys))
然后构建模式:

pat := "\\b(" + strings.Join(keys, `|`) + ")\\b"
// fmt.Println(pat) // => \b(you're|your|you|me|my|I)\b
该模式将
您的
我的
,或
作为整个单词进行匹配

res := regexp.MustCompile(pat).ReplaceAllStringFunc(capturedString, func(m string) string {
    return reflections[m]
})
上面的代码创建一个regex对象,并用相应的
反射值替换所有匹配项


请参阅。

此处要实现的是用特定替换替换特定字符串。使用字符串键和值的映射更容易实现这一点,其中每个唯一键都是要搜索的文本短语,值是要替换的文本

以下是定义反射的方式:

接下来,您需要按长度降序获取密钥(如下所示):

然后在函数中:

var keys []string
for key, _ := range reflections {
    keys = append(keys, key)
}
sort.Sort(ByLenDesc(keys))
然后构建模式:

pat := "\\b(" + strings.Join(keys, `|`) + ")\\b"
// fmt.Println(pat) // => \b(you're|your|you|me|my|I)\b
该模式将
您的
我的
,或
作为整个单词进行匹配

res := regexp.MustCompile(pat).ReplaceAllStringFunc(capturedString, func(m string) string {
    return reflections[m]
})
上面的代码创建一个regex对象,并用相应的
反射值替换所有匹配项


请参阅。

注意,示例文本包含卷曲撇号,而正则表达式仅包含单素数(当您按下单引号键时,实际得到的是没有文字处理器中的某种“智能引号”功能)。请注意,
r1
模式不包含任何捕获组,当替换为
$1
时,只需删除匹配项。因此,
capturedString:=r1.ReplaceAllString(str,“$1”)
=
capturedString:=r1.ReplaceAllString(str,”)
。我知道它不是代码中最重要的部分,但请确保您理解它在做什么。我将在完成第一个问题时替换它。它取代了“我是,我是,我是”这句话。我有一个句子连接到它之后,我有一个词你正在改变正确。好的,看。对不起,我赶时间,但你会明白要点的。谢谢你,这是一个很好的解决方案。我发现我只需要将正则表达式更改为边界变量。我会把我的解决方案贴在下面。再次感谢!!请注意,示例文本包含卷曲撇号,而正则表达式仅包含单素数(当您按下单引号键时,实际得到的是没有文字处理器中的某种“智能引号”功能)。请注意,
r1
模式不包含任何捕获组,当替换为
$1
时,只需删除匹配项即可