替换引号中的任何字符串

12

问题:

我找不到一种一致的方法来将引号之间的随机字符串替换为我想要的特定字符串。任何帮助都将不胜感激。

示例:

String str1 = "test=\"-1\"";

应该变成

String str2 = "test=\"31\"";

但也适用于

String str3 = "test=\"foobar\"";

基本上我想把这个转变一下

String str4 = "test=\"antyhingCanGoHere\"";

变成这样

String str4 = "test=\"31\"";

尝试过的:

如何在不使用RegexOptions枚举的情况下实现大小写不敏感的正则表达式

如何使用正则表达式进行大小写不敏感的字符串替换?

如何使用正则表达式将AnyText:和<usernameredacted@example.com>之间的任何字符替换为空字符串?

替换两个出现次数之间的字符串

替换两个字符串之间的一个字符串

当前代码:

    Regex RemoveName = new Regex("(?VARIABLE=\").*(?=\")", RegexOptions.IgnoreCase);
    String convertSeccons = RemoveName.Replace(ruleFixed, "31");

返回错误:

System.ArgumentException was caught
  Message=parsing "(?VARIABLE=").*(?=")" - Unrecognized grouping construct.
  Source=System
  StackTrace:
       at System.Text.RegularExpressions.RegexParser.ScanGroupOpen()
       at System.Text.RegularExpressions.RegexParser.ScanRegex()
       at System.Text.RegularExpressions.RegexParser.Parse(String re, RegexOptions op)
       at System.Text.RegularExpressions.Regex..ctor(String pattern, RegexOptions options, Boolean useCache)
       at System.Text.RegularExpressions.Regex..ctor(String pattern, RegexOptions options)
       at application.application.insertGroupID(String rule) in C:\Users\winserv8\Documents\Visual Studio 2010\Projects\application\application\MainFormLauncher.cs:line 298
       at application.application.xmlqueryDB(String xmlSaveLocation, TextWriter tw, String ruleName) in C:\Users\winserv8\Documents\Visual Studio 2010\Projects\application\application\MainFormLauncher.cs:line 250
  InnerException: 

找到答案

string s = Regex.Replace(ruleFixed, "VARIABLE=\"(.*)\"", "VARIABLE=\"31\"");
ruleFixed = s;

我在之前发布的一个链接 Replace any character in between AnyText: and with an empty string using Regex? 中找到了这段代码示例,但由于我认为它不能处理我需要的内容,所以跳过了这个语法。


你期望的结果是什么?你能澄清一下你想要的最终结果吗? - MethodMan
@DJKRAZE 我刚刚添加了更多对我想要的东西的描述。基本上我想把这个,String str4 = "test="antyhingCanGoHere"";,变成这个,String str4 = "test="31"";。 - toosweetnitemare
1
你尝试过使用简单的正则表达式 \".*\" 吗? - Ilya Ivanov
你能为每个输入提供一个样本输出来澄清吗? - Saleh Omar
1
将此内容添加到您的问题中。同时删除帖子中与您遇到的问题无关的所有链接。 - MethodMan
11个回答

3
var str1 = "test=\"foobar\"";
var str2 = str1.Substring(0, str1.IndexOf("\"") + 1) + "31\"";

如果需要,请添加对 IndexOf != -1 的检查。

这不能满足他搜索特定值的用例。 - ErikE
@ErikE他不想搜索特定值,而是替换引号内的随机值。 - Magnus
澄清一下:这并不测试格式 test="foobar"。它只是找到任何旧的 "foobar",甚至是 donotchangethis="foobar"。此外,您没有替换原始字符串的内容,而是创建了一个新字符串。他要替换的整个字符串可能有多行!这不是匹配的情况。 - ErikE
1
@ErikE 我会说 donotchangethis="foobar" 应该被更改,因为要求是在引号内设置任何值。此外,由于字符串是不可变的,所以没有所谓的“替换”。 - Magnus
我可能错误地认为字符串中存在单个键/值对之外的其他部分。然而,如果您仔细阅读 OP(注意他提出的解决方案),您将看到要求并不是“任何带引号的值”。 - ErikE
@ErikE 我想你可能是对的,但如果没有查看他的代码并阅读问题:“用特定字符串替换引号之间的随机字符串”,人们可能会认为这就是他想要的。 - Magnus

2

我不确定我是否理解你的意思,但如果你想替换字符串中的所有字符,为什么不使用简单的正则表达式呢?

String str = "test=\"-\"1\"";

Regex regExpr = new Regex("\".*\"", RegexOptions.IgnoreCase);
String result = regExpr.Replace(str , "\"31\"");

Console.WriteLine(result);

打印:

test="31"

注意: 您可以利用普通的 XAttribute

String ruleFixed = "test=\"-\"1\"";

var splited = ruleFixed.Split('=');
var attribute = new XAttribute(splited[0], splited[1]);

attribute.Value = "31";

Console.WriteLine(attribute);//prints test="31"

1
那可能太过贪心了,我建议使用[^"]*。但根据实际用例可能不是这样。 - Bobson
我知道,我认为我们需要贪心一点,让我再确认一下。好的,他写了“随机字符串”。我会更新代码,提供两个选项。 - Ilya Ivanov
完整的正则表达式是 \"[^\"]*\",它基本上是两个双引号之间不是双引号的任何内容。 - Steve Konves
1
@Steve,仅根据标题回答问题而不查看问题文本的解释是正常的吗? - ErikE
@ErikE 当然不是!不过对于一条几乎正确的评论做出回应,则另当别论 :) - Steve Konves
显示剩余4条评论

1

如果您的字符串中除了key="value"键值对之外还有其他内容,那么您需要使值匹配部分匹配引号,否则它将从字符串中的第一个值一直匹配到最后一个引号标记。

如果是这样,请尝试以下方法:

Regex.Replace(ruleFixed, "(?<=VARIABLE\s*=\s*\")[^\"]*(?=\")", "31");

这里使用负向回顾来匹配VARIABLE="部分(可选周围的空格,因此VARIABLE = "也可以工作),并使用负向前瞻来匹配结束的",而不包括在最终匹配中的前瞻/回顾,使您只需替换所需的值。

如果没有,那么您的解决方案将会起作用,但不是最佳选择,因为您必须在替换文本中重复值和引号标记。


那么如何使用正向预查(变量名称和前面的双引号)和后顾(尾随双引号):(?<=test\s*=\s*\")[^\"]*(?=\"),这样你就可以只用新值替换而不是整个字符串。 - Steve Konves
你也可以使用 ? - 如果你尝试匹配 .*?,那么它将执行非贪婪模式匹配,不包括闭合引号。 - levelnis
@Steve 我认为这将是一个更好的答案,只替换需要更换的部分。 - ErikE

1
var parts = given.Split('=');
return string.Format("{0}=\"{1}\"", parts[0], replacement);

如果它以 wrongkey="value" 开头,那么你错误地替换了它,而没有只关注 rightkey="value" - ErikE
@ErikE: 这假设 given 是被错误地发现,而不是这个函数关心的东西。 - Austin Salonen

1
假设引号内的字符串本身不包含引号,你可以使用这个通用模式来查找前缀和后缀之间的位置:
(?<=prefix)find(?=suffix)

根据您的情况

(?<=\w+=").*?(?=")

在这里,我们使用前缀\w+=",其中\w+表示单词字符(变量),="是等号和引号。

我们想要找到任何.*?,直到遇到下一个引号。

后缀只是引号"

string result = Regex.Replace(input, "(?<=\\w+=\").*?(?=\")", replacement);

0
     String str1 = "test=\"-1\"";
     string res = Regex.Replace(str1, "(^+\").+(\"+)", "$1" + "31" + "$2");

0
var pattern = "\"(.*)?\"";
var regex = new Regex(pattern, RegexOptions.IgnoreCase);
var replacement = regex.Replace("test=\"hereissomething\"", "\"31\"");

这样做行不通...它返回 "test="31"",他想要去掉结尾的 "" 以便 `yield "test="31``。 - MethodMan
不,他不想这样做——除非我完全误解了问题,看起来他想要替换在开头和结尾引号之间的字符串——问题中所有示例都包含两组引号。 - levelnis
@levelnis他只想要以特定值引入的字符串,例如key1="whatever"。他不想匹配key2="whatever" - ErikE
@DJKRAZE,我认为你误解了需求。 - ErikE
@levelins 你可能是对的,如果是这样请原谅我。我可能错误地认为输入字符串中除了这个值还有其他值。 - ErikE
我并不关注这个问题,我认为提问者对自己想要的东西感到困惑。 - MethodMan

0

除非您的“ruleFixed”字符串不包含任何其他引号,否则此操作将无法正常工作。这是真的吗?请参阅我的答案,了解如何在引号内部的值结束时停止匹配。 - ErikE

0
String str1 = "test=\"-1\"";
string[] parts = str1.Split(new[] {'"'}, 3);
string str2 = parts.Length == 3 ? string.Join(@"\", parts.First(), "31", parts.Last()) : str1;

0

我对正则表达式(RegEx)不是很擅长,但你可以使用字符串函数创建一个简单的扩展方法(ExtensionMethod)来完成这个任务。

public static class StringExtensions
{
    public static string ReplaceBetweenQuotes(this string str, string replacement)
    {
        if (str.Count(c => c.Equals('"')) == 2)
        {
            int start = str.IndexOf('"') + 1;
            str = str.Replace(str.Substring(start, str.LastIndexOf('"') - start), replacement);
        }
        return str;
    }
}

使用方法:

 String str3 = "test=\"foobar\"";
 str3 = str3.ReplaceBetweenQuotes("31");

returns: "test=\"31\"" 

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