Как выбрать первые символы с пользовательской границей слова? - PullRequest
0 голосов
/ 19 октября 2019

У меня есть тестовые случаи с серией слов вроде этого:

    {
        input:    "Halley's Comet",
        expected: "HC",
    },
    {
        input:    "First In, First Out",
        expected: "FIFO",
    },
    {
        input:    "The Road _Not_ Taken",
        expected: "TRNT",
    },

Я хочу, чтобы с одним регулярным выражением совпадали все первые буквы этих слов, избегайте совпадения символа char: "_" какпервая буква и счетная одинарная кавычка в слове.
В настоящее время у меня есть это регулярное выражение, работающее с синтаксисом pcre, но не с пакетом regexp Go: (?<![a-zA-Z0-9'])([a-zA-Z0-9'])
Я знаю, что обходные пути не поддерживаются Go, но я ищудля хорошего способа сделать это.

Я также использую эту функцию, чтобы получить массив всех строк: re.FindAllString(s, -1)

Спасибо за помощь.

Ответы [ 2 ]

2 голосов
/ 19 октября 2019

Что-то, что играет с классами символов и границами слов, должно быть достаточно:

\b_*([a-z])[a-z]*(?:'s)?_*\b\W*

demo

Использование:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`(?i)\b_*([a-z])[a-z]*(?:'s)?_*\b\W*`)
    fmt.Println(re.ReplaceAllString("O'Brian's dog", "$1"))

}
0 голосов
/ 20 октября 2019

ftr, регулярное выражение без решения

package main

import (
    "fmt"
)

func main() {
    inputs := []string{"Hallمرحباey's Comet", "First In, First Out", "The Road _Not_ Taken", "O'Brian's Dog"}
    c := [][]string{}
    w := [][]string{}
    for _, input := range inputs {
        c = append(c, firstLet(input))
        w = append(w, words(input))
    }
    fmt.Printf("%#v\n", w)
    fmt.Printf("%#v\n", c)
}

func firstLet(in string) (out []string) {
    var inword bool
    for _, r := range in {
        if !inword {
            if isChar(r) {
                inword = true
                out = append(out, string(r))
            }
        } else if r == ' ' {
            inword = false
        }
    }
    return out
}

func words(in string) (out []string) {
    var inword bool
    var w []rune
    for _, r := range in {
        if !inword {
            if isChar(r) {
                w = append(w, r)
                inword = true
            }
        } else if r == ' ' {
            if len(w) > 0 {
                out = append(out, string(w))
                w = w[:0]
            }
            inword = false
        } else if r != '_' {
            w = append(w, r)
        }
    }
    if len(w) > 0 {
        out = append(out, string(w))
    }
    return out
}

func isChar(r rune) bool {
    return (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z')
}

выходы

[][]string{[]string{"Hallمرحباey's", "Comet"}, []string{"First", "In,", "First", "Out"}, []string{"The", "Road", "Not", "Taken"}, []string{"O'Brian's", "Dog"}}
[][]string{[]string{"H", "C"}, []string{"F", "I", "F", "O"}, []string{"T", "R", "N", "T"}, []string{"O", "D"}}
...