除序数指示符外,用于分割数字和字符串的正则表达式

3

寻找一个正则表达式,在用户输入中连接数字和字符串的地方引入空格,但是不包括序数词标识符,例如1st, 11th, 22nd, 33rd, 44th等。

所以这个字符串:

Hi is this available 18dec to 21st dec

返回为:

Hi is this available 18 dec to 21st dec

使用以下表达式:

 Regex.Replace(value, @"(\d)(\p{L})", "$1 $2"))

提供

您好,这个从12月18日到12月21日是否可用?

编辑:

根据@juharr的评论,应将12月12日更改为12月12日。


你想把“dec12th”改成“dec 12th”,对吗? - juharr
@juharr 正确 - Matt Evans
@MatthewEvans 请将此要求添加到问题中。 - Wiktor Stribiżew
@WiktorStribiżew - 已完成 - Matt Evans
这确实让一切变得更加困难,我会更新代码。 - Wiktor Stribiżew
终于搞定了,正在发布。 - Wiktor Stribiżew
1个回答

3
您可以使用以下解决方案:
var s = "Hi is this available 18dec to 21st dec 2nd dec 1st jan dec12th";
var res = Regex.Replace(s, @"(\p{L})?(\d+)(st|[nr]d|th|(\p{L}+))", repl);
Console.WriteLine(res);
// => Hi is this available 18 dec to 21st dec 2nd dec 1st jan dec 12th

// This is the callback method that does all the work
public static string repl(Match m) 
{
    var res = new StringBuilder();
    res.Append(m.Groups[1].Value);  // Add what was matched in Group 1
    if (m.Groups[1].Success)        // If it matched at all...
        res.Append(" ");            // Append a space to separate word from number
    res.Append(m.Groups[2].Value);  // Add Group 2 value (number)
    if (m.Groups[4].Success)        // If there is a word (not st/th/rd/nd suffix)...
        res.Append(" ");            // Add a space to separate the number from the word
    res.Append(m.Groups[3]);         // Add what was captured in Group 3
    return res.ToString();
}

请查看C#演示

所使用的正则表达式为

(\p{L})?(\d+)(st|[nr]d|th|(\p{L}+))

请参见在线演示。它匹配:
- (\p{L})? - 可选的第一组,匹配一个字母。 - (\d+) - 第二组:一个或多个数字。 - (st|[nr]d|th|(\p{L}+)) - 第三组匹配以下备选项:
- st - st - [nr]d - ndrd - th - th - (\p{L}+) - 第四组:任何一个或多个 Unicode 字母。 repl 回调方法接受匹配对象,并使用其他逻辑基于可选组是否匹配来构建正确的替换字符串。
如果需要进行不区分大小写的搜索和替换,请传递 RegexOptions.IgnoreCase 选项,如果只想匹配 ASCII 数字与 \d(请注意,即使将此选项传递给正则表达式,\p{L} 仍将匹配任何 Unicode 字母),请传递 RegexOptions.ECMAScript

@MatthewEvans 但是你有足够的时间提出其他问题。请参见问题下方juharr的评论。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接