正则表达式匹配两个字符之间的多个数字组

4

我有一个字符串,长这样:

<@399969178745962506> hello to <@!104729417217032192>

我有一个包含以下内容的字典:

{"399969178745962506", "One"},
{"104729417217032192", "Two"}

我的目标是将<@399969178745962506>替换成那个数字键的值,而在这种情况下,它应该是One

Regex.Replace(arg.Content, "(?<=<)(.*?)(?=>)", m => userDic.ContainsKey(m.Value) ? userDic[m.Value] : m.Value);

我的当前正则表达式如下:(?<=<)(.*?)(?=>),它仅匹配在<>之间的内容,在这种情况下会匹配@399969178745962506@!104729417217032192
我不能忽略@符号,因为并不是每次都有!符号。所以最好只使用类似于\d+的内容来获取数字。
我需要找出如何只获取<>之间的数字,但我无论如何也想不出来。
非常感谢您的帮助!
4个回答

3

在C#中,您可以使用两种方法:基于后瞻的(因为后瞻模式可以是可变宽度)和基于捕获组的方法。

基于后瞻的方法

可以轻松帮助您以正确上下文获取数字的模式是

(?<=<@!?)\d+(?=>)

请参考正则表达式演示

(?<=<@!?)是一个正向后行参照,它要求当前位置左侧紧接着的字符是<=<=! ,并且(?=>)是一个正向前瞻,它要求当前位置右侧紧接着的字符是>

捕获方法

您可以使用以下模式来捕获预期<...>子字符串中的数字:

<@!?(\d+)>

细节

  • <@ - 字面意义上的<@子字符串
  • !? - 可选感叹号符号
  • (\d+) - 捕获第1个匹配一个或多个数字的组
  • > - 字面上的>符号。

请注意,您需要的值可以通过match.Groups[1].Value访问,如上面的代码段所示。

用法:

var userDic = new Dictionary<string, string> {
        {"399969178745962506", "One"},
        {"104729417217032192", "Two"}
    };
var p =  @"<@!?(\d+)>";
var s = "<@399969178745962506> hello to <@!104729417217032192>";
Console.WriteLine(
    Regex.Replace(s, p, m => userDic.ContainsKey(m.Groups[1].Value) ?
        userDic[m.Groups[1].Value] : m.Value
    )
); // => One hello to Two
// Or, if you need to keep <@, <@! and >
Console.WriteLine(
    Regex.Replace(s, @"(<@!?)(\d+)>", m => userDic.ContainsKey(m.Groups[2].Value) ?
        $"{m.Groups[1].Value}{userDic[m.Groups[2].Value]}>" : m.Value
    )
); // => <@One> hello to <@!Two>

查看C#演示

2
为了从给定的格式中提取数字,可以使用以下正则表达式模式:

使用此正则表达式模式仅提取数字:

(?<=<@|<@!)(\d+)(?=>)

看它在实际操作中的效果:https://regexr.com/3j6ia

0

您可以使用非捕获组来排除需要匹配的模式的某些部分:

(?<=<)(?:@?!?)(.*?)(?=>)

或者你可以给内部组命名,并使用命名组来获取它:

(?<=<)(?:@?!?)(?<yourgroupname>.*?)(?=>)

通过m.Groups["yourgroupname"].Value访问它 - 更多信息请参见如何在.NET Regex中访问命名捕获组?


有没有办法只获取捕获组中的数字?这样<@399969178745962506> hello to <@!104729417217032192>就会变成[0] = 399969178745962506,[1] = 104729417217032192 - Ezzy
@Ezzy 在 .* 之前的一个 non-capturing 组中使 @! 变为可选项 - 请查看更改。 - Patrick Artner

0

正则表达式: (?:<@!?(\d+)>)

细节:

(?:) 非捕获组

<@ 匹配字符 <@ 字面意义

? 匹配零次或一次

(\d+) 第1个捕获组 \d+ 匹配数字(等同于 [0-9])

正则表达式演示

string text = "<@399969178745962506> hello to <@!104729417217032192>";
Dictionary<string, string> list = new Dictionary<string, string>() { { "399969178745962506", "One" }, { "104729417217032192", "Two" } };

text = Regex.Replace(text, @"(?:<@!?(\d+)>)", m => list.ContainsKey(m.Groups[1].Value) ? list[m.Groups[1].Value] : m.Value);

Console.WriteLine(text); \\ One hello to Two
Console.ReadLine();

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