C# 正则表达式出现意外结果
本文关键字:意外 结果 正则表达式 | 更新日期: 2023-09-27 18:33:11
我有一个正则表达式,它应该匹配字符串中本身的"S"。我使用了以下版本,它通过拒绝字符串"圣查尔斯"来工作:
regex = new Regex(@"(^|'s)(?<stuff>S?)('s|$)");
Match match = regex.Match("Saint Charles");
匹配按预期失败。
我的问题是下面的第二个版本为什么接受字符串:
regex = new Regex(@"(^|'b)(?<stuff>S?)('b|$)");
Match match = regex.Match("Saint Charles");
比赛成功了,但我预计它会失败。
更新:以下是我的目标的一些背景:
我有一个拼写错误或需要不同措辞的位置列表:
string[] locationNames =
{
"Ponte Vedra Beac",
"Newton Upper Fal",
"Howey In The Hil",
"Mc Donough",
"East Mc Dowell",
"Saint Charles",
"Cape Saint Clair",
"Marine On Saint",
"W Mifflin Fin",
"Mt Sylvan",
"Bromley Mtn",
"S Richmond Hill"
};
通过查看数据,我确定一些替换应该发生在位置名称的末尾,一些替换应该发生在开头,而另一些则发生在两者之间的任何地方。
我正在使用字典来确定 1(正确的替换和 2( 所需的正则表达式类型。
var alternateSpellings = new Dictionary<string, string>()
{
{"Beac$", "Beach"},
{"Fal$", "Falls"},
{"Hil$", "Hills"},
{"Mc ", "Mc"},
{"'bMt'b", "Mount"},
{"'bMtn'b", "Mountain"},
{"'bS'b", "South"},
{"'bSaint'b", "St."}
};
我遍历列表,并根据嵌入的元字符选择一个正则表达式。选项包括:
regex = new Regex(".*(?<stuff>" + alternateSpelling.Key.Replace("$", "") + ")$");
或
regex = new Regex(@"(^|'s)(?<stuff>" + alternateSpelling.Key.Replace("'b", "") + @")('s|$)");
注意:我已经放弃了'b
,转而支持's
或
regex = new Regex(".*(?<stuff>" + alternateSpelling.Key + ").*");
一旦我找到匹配项,我就会进行替换...
if (match.Success)
{
var stuff = match.Groups["stuff"].Value;
var stuffPosition = match.Groups["stuff"].Index;
newLocationName = locationName.Remove(stuffPosition, stuff.Length).Insert(stuffPosition, alternateSpelling.Value);
}
(^|'b)(?<stuff>S?)('b|$)
如何匹配Saint Charles
^ => Start of String
Saint Charles
^
S? => which is optional. Tries to match
Saint Charles
^
('b|$) => Tries for 'b or $ after S. But cannot match. Backtracks to start
Saint Charles
^
'b => Matches at the start of the string
Saint Charles
^
因此成功
-
'b
匹配单词边界。那是在字符串的开头和结尾
如何更正
通过删除?
来匹配仅包含简单修改S
单词会有所帮助
(^|'b)(?<stuff>S)('b|$)
正则表达式示例
S? 与 S 匹配零次或一次。因此,在字符串的开头有一个匹配项,即
(start of string)(zero occurrences of S)(word boundary)
尝试只使用 S 而不是 S?
MSDN 上的单词边界
''b 锚点指定匹配必须在边界上进行 在单词字符(''w 语言元素(和非单词之间 字符(''W 语言元素(。单词字符由 字母数字字符和下划线;非单词字符是任何 不是字母数字或下划线的字符。(更多 信息,请参阅正则表达式中的字符类。比赛 也可能出现在单词边界的开头或结尾 字符串。
*强调是我的答案。