正则无法匹配含双引号的Yii::t翻译字符串问题排查
Let's break down what was going wrong with your regex and fix it properly.
The Root Issues
You initially suspected single vs double quotes were the problem, but as you later realized, the main blocker was unhandled whitespace around the comma separating the category and message parameters. On top of that, your original regex didn't enforce matching opening/closing quote pairs (while this didn't break your mixed-quote example, it's a solid practice to add this guard).
Limitations of Your Original Regex
re := regexp.MustCompile(`(Yii::t\()(\'|\")(.*?)(\'|\")\,(\'|\")(.*?)(\'|\")\)`)
- The
\,only matches a comma with no surrounding whitespace. Lines likeYii::t("backend", "Search...")have a space after the comma, so this part of the regex failed to align. - While it allows single/double quotes, it doesn't ensure the opening quote matches the closing one (e.g., it would incorrectly flag a malformed string like
Yii::t('backend", "My Profile')as valid).
The Fixed Regex
Here's an improved version that handles whitespace, supports mixed quote types (like "backend", 'Sounds'), and ensures opening/closing quotes match:
re := regexp.MustCompile(`Yii::t\((?P<quote1>['"])(.*?)\k<quote1>\s*,\s*(?P<quote2>['"])(.*?)\k<quote2>\)`)
Regex Breakdown
Yii::t\(: Matches the start of the translation method call(?P<quote1>['"]): Captures the first quote (single or double) and names itquote1(.*?): Non-greedily matches the category string until it hits the matching closing quote\k<quote1>: Matches the same quote type as the opening category quote\s*,\s*: Matches the comma, allowing any number of whitespace characters before/after it(?P<quote2>['"]): Captures the message's opening quote (can differ from the category's quote)(.*?): Non-greedily matches the message string until its matching closing quote\k<quote2>\): Matches the message's closing quote and the final parenthesis
Test It With Your Cases
Here's a complete Go example to verify it works for all your test scenarios:
package main import ( "fmt" "regexp" ) func main() { testLines := []string{ `Yii::t('backend','My Profile')`, `Yii::t('backend','Log Out')`, `Yii::t("backend", "Search...")`, `Yii::t("backend", 'Sounds')`, } re := regexp.MustCompile(`Yii::t\((?P<quote1>['"])(.*?)\k<quote1>\s*,\s*(?P<quote2>['"])(.*?)\k<quote2>\)`) for _, line := range testLines { matches := re.FindAllString(line, -1) fmt.Printf("Input: %s\nMatched: %v\n\n", line, matches) } }
Running this will output matches for all your test cases, including those with spaces around commas and mixed quote types.
内容的提问来源于stack exchange,提问作者TheDevWay




