在长字符串中查找以@@开头并以@@结尾的所有单词

9

我有一个相当大的字符串。在这个大字符串中,我想要获取所有以@@开头并以@@结尾的唯一单词。@@之间可以是文本、数字、字母数字或任何其他字符。

一旦我获取了所有以@@开头并以@@结尾的唯一单词,我想要使用与不同数组中的键匹配的值替换每个单词。

正在寻找C#的解决方案。


我不明白为什么有那么多人坚持使用正则表达式,当有string.Splitstring.StartsWithstring.Replace这些同样好用的方法(对我来说更易读)。 - default
7个回答

12

尝试这个正则表达式:

@@\b\S+?\b@@

示例代码:

List<string> lst = new List<string>();
MatchCollection mcol = Regex.Matches(sampleString,@"@@\b\S+?\b@@");

foreach(Match m in mcol)
{
    lst.Add(m.Tostring());
}

在这里,lst包含匹配的值,比较每个值并根据您的标准进行替换。

示例实时演示


你的模式不合适。\b 会导致模式在不想要的偏移处匹配。应该使用以下模式:*@@\b(?<word>.+?)\b@@* - User 12345678
@ByteBlast,按照您的建议操作后,它起作用了。除了正则表达式之外,您的代码运行良好。 - Shiras
@ByteBlast:@@\b(.+?)\b@@ 也不一定有效。它假设“单词”的第一个和最后一个字符将始终是单词字符(即匹配\w+的字符)。从目前为止OP所说的内容来看,这似乎不是一个安全的假设。如果您知道第一个和最后一个字符始终是单词字符,则\b是多余的。 - Alan Moore
在字符串“@@bb@@ @@cc@@ @@sahasjah@@ @@bb@@ @@hello @@how @invensys@@”中,输出应该是@@bb@@ @@cc@@ @@sahasjah@@ @@bb@@。目前它显示了@@hello,这是错误的,因为hello后面有一个空格。请给予建议。 - Shiras
@NeverHopeless,感谢您的快速响应。那个可以用。 - Shiras
显示剩余2条评论

1

尝试以下代码(使用 Regex.Replace 方法):

string s = @"@@Welcome@@ to @@reg-ex@@ @@world@@.";
Dictionary<string, string> sub = new Dictionary<string,string>{
    { "@@reg-ex@@", "regular expression" },
    { "@@world@@", "hell" },
};
Regex re = new Regex(@"@@.*?@@");
Console.WriteLine(re.Replace(s, x => {
    string new_x;
    return sub.TryGetValue(x.ToString(), out new_x) ? new_x : x.ToString();
}));

打印:

@@Welcome@@ to regular expression hell.

在字符串“@@bb@@ @@cc@@ @@sahasjah@@ @@bb@@ @@hello @@how @invensys@@”中,输出应该是“@@bb@@ @@cc@@ @@sahasjah@@ @@bb@@”,目前它还显示了“@@hello”,这是错误的,因为在hello后面有一个空格。请给予建议。 - Shiras

1

使用正则表达式和Linq的示例

string text = "@@bb@@@@cc@@@@sahasjah@@@@bb@@";
var matches = Regex.Matches(text, @"@@[^@]*@@");
var uniques = matches.Cast<Match>().Select(match => match.Value).ToList().Distinct();

1
你为什么要使用 Singleline 选项?你的正则表达式中没有点 (.)。 - Alan Moore
在字符串“@@bb@@ @@cc@@ @@sahasjah@@ @@bb@@ @@hello @@how @invensys@@”中,输出应该是“@@bb@@ @@cc@@ @@sahasjah@@ @@bb@@”,目前它显示了“@@hello”,这是错误的,因为在hello后面有一个空格。请给予建议。 - Shiras

0
你可以尝试以下操作。
Regex regex = new Regex("@@(.*)@@");

或者,如果您不想使用正则表达式,请使用以下内容(我认为更容易理解)

var splittedString = yourString.Split(new string[] { "xx" }, StringSplitOptions.None);

在字符串“@@bb@@ @@cc@@ @@sahasjah@@ @@bb@@ @@hello @@how @invensys@@”中,输出应该是“@@bb@@ @@cc@@ @@sahasjah@@ @@bb@@”,目前它还显示了“@@hello”,这是错误的,因为hello后面有一个空格。请指教。 - Shiras

0

试试这个,伙计……

string yourString = ""; // Load your string
string[] splits = Regex.Split(yourString, "[ \n\t]"); //Split the long string by spaces, \t and \n
foreach (string str in splits)
{
    if(Regex.IsMatch(str, "^^@@.*?@@$$")) // Find words starting and ending with @@
    {
        // You may replace either splits values or build a new string according your specification
    }
}

0

我不会使用正则表达式来做这件事。这个方法更快:

//Pseudo code
string[] parts = yourLongString.split("@@");
for(i=0;i<parts.length;i++){
    if(parts[i].indexOf(' ')<0){
        // there is no space, it is a keyword
        parts[i]=yourDictionary[parts[i]];
    }
}
yourFinalText=parts.join(' ');

在长字符串中,以@@samplestring@@开头的关键字可能会重复多次。如果我能像你提到的那样查找和替换就很好了。但是,我如何将长字符串中所有唯一的关键字放入数组或列表中?在长字符串中可能会有以@@开头但不以@@结尾的单词。我想在我的关键字列表中忽略它们。我的关键字列表应该只包含以@@开头并以@@结尾的单词。 - Shiras
所以只需更改循环。检查空格。如果没有空格,则它是关键字,您必须替换它。我更新了代码。 - bokan

0

在字符串“@@bb@@ @@cc@@ @@sahasjah@@ @@bb@@ @@hello @@how @invensys@@”中,输出应该是“@@bb@@ @@cc@@ @@sahasjah@@ @@bb@@”,目前它还显示了“@@hello”,这是错误的,因为在hello后面有一个空格。请指导。 - Shiras

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