C# 将混合字符串(SVG路径)中的数字乘以公因数

C# 将混合字符串(SVG路径)中的数字乘以公因数,c#,.net,string,svg,C#,.net,String,Svg,有没有一种简单的方法可以将混合(文本和数字)字符串中的所有数字乘以一个因子 我有一个SVG路径,例如:d=“M 0,20 40,20 40,80 0,80 z” 该字符串包括数对,由,分隔。每个数字也可以是双精度值。这些数字对表示x、y坐标 如何将该字符串中的所有数字对(例如)乘以因子2?假设我们有这样一个字符串 var d = "M 0,20 40,20 40,80 0,80 z"; 我们想把所有整数乘以2。我们使用一个重载Regex.Replace函数,该函数接受一个字符串,该函数将应用于

有没有一种简单的方法可以将混合(文本和数字)字符串中的所有数字乘以一个因子

我有一个SVG路径,例如:
d=“M 0,20 40,20 40,80 0,80 z”

该字符串包括数对,由
分隔。每个数字也可以是双精度值。这些数字对表示x、y坐标


如何将该字符串中的所有数字对(例如)乘以因子2?

假设我们有这样一个字符串

var d = "M 0,20 40,20 40,80 0,80 z";
我们想把所有整数乘以2。我们使用一个重载
Regex.Replace
函数,该函数接受一个字符串,该函数将应用于已找到的每个匹配项,并用该函数返回的值替换该匹配项

在函数中,我们尝试用模式将匹配字符串解析为字符串,如果成功,我们将其加倍并返回,如果失败,我们返回原始匹配字符串

d = Regex.Replace(d, "([0-9]{0,})", (m) =>
{
    int i;
    if (int.TryParse(m.Value, out i))
    {
        return (2*i).ToString();
    }
    return m.Value;
}, RegexOptions.None);
Console.WriteLine(d);

为了我自己的娱乐,这里有一个答案

var d = "M 0,20 40,20 40,80 0,80 z";
var split = d.Split(' ');

string result = string.Empty;

foreach (var element in split)
{
    if (element.Contains(","))
    {
        var couple = element.Split(',');
        int val1, val2;

        bool isNum = int.TryParse(couple[0], out val1);
        isNum &= int.TryParse(couple[1], out val2);

        if (isNum) // could be removed and simplified if there are never "," between something else than two numbers
        {
            result += " " + (val1 * 2).ToString() + "," + (val2 * 2).ToString();
        }
        else
        {
            result += " " + element;
        }
    }
    else
    {
        result += " " + element;
    }
}

result = result.Trim();
Console.WriteLine(result);
简化版本(无类型检查,如果逗号周围有数字以外的内容,将引发异常):


试试这样的

List<double> myList = Regex.Replace("M 0,20 40,20 40,80 0,80 z", @"[^\d\, ]", "").Trim().Split(new char[] { ' ' }).ToList<String>().ConvertAll(item => double.Parse(item)*2);
string originalText = "M 0,20 40,20 40,80 0,80 z";
string newText = MultiplyNumbersInString(originalText, 2);
List myList=Regex.Replace(“M 0,20 40,20 40,80 0,80 z”、@“[^\d\,]”、“”)。Trim().Split(新字符[]{'})。ToList().ConvertAll(项=>double.Parse(项)*2);
要返回字符串,只需使用

  String Str= String.Join(" ", (Regex.Replace("M 0,20 40,20 40,80 0,80 z", @"[^\d\, ]", "").Trim().Split(new char[] { ' ' }).ToList<String>().ConvertAll(item => (double.Parse(item)*2).ToString()).ToArray()));
String Str=String.Join(“,(Regex.Replace(“m0,2040,2040,800,80z)”,@“[^\d\,]”,”).Trim().Split(newchar[]{'}.ToList().ConvertAll(item=>(double.Parse(item)*2.ToString().ToArray());

为了好玩,我用linq做了一个通用函数:

public string MultiplyNumbersInString(string text, int multiplier)
{
    double n;
    return string.Join(" ",
        (from t in text.Split(' ')
         select (double.TryParse(t, out n) 
            ? (double.Parse(t) * multiplier).ToString("F") 
            : t))
        .ToList());
    }
} 
您可以提供要更改的字符串和乘数,它将相应地更改您的字符串。你可以这样称呼它

List<double> myList = Regex.Replace("M 0,20 40,20 40,80 0,80 z", @"[^\d\, ]", "").Trim().Split(new char[] { ' ' }).ToList<String>().ConvertAll(item => double.Parse(item)*2);
string originalText = "M 0,20 40,20 40,80 0,80 z";
string newText = MultiplyNumbersInString(originalText, 2);
编辑:

@CPA在阅读了您的评论和您对我的答案的拒绝编辑后,这里有两个函数可以满足您的要求

第一个使用lamdas的是您在“拒绝编辑”中编写的:

public string MultiplyNumbersInString(string text, int multiplier)
{
    return string.Join(" ", text.Split(' ')
                            .Select(t1 => (t1.Contains(',')) 
                            ? (string.Join(",", t1.Split(',')
                            .Select(t2 => (double.Parse(t2) * multiplier).ToString()))) 
                            : t1)); 
}
这是我在没有lamdas的情况下的函数

public string MultiplyNumbersInString(string text, int multiplier)
{
    return string.Join(" ", (from t in text.Split(' ')
                             select (t.Contains(",")
                             ? string.Join(",",
                                (from t1 in t.Split(',')
                                 select (double.Parse(t1) * multiplier).ToString()))
                             : t)).ToList());
}


欢迎来到堆栈溢出。这不是一个好的提问方式。到目前为止,你有没有尝试过解决你的问题?先表现出你的努力,这样人们才能表现出他们的努力。请阅读,并作为一个开始。请在问题中包括您期望的结果。性能方面的考虑如何?这个符号不是你使用的工具中的标准符号吗?它已经集成了你需要的操作符了?实现您要求的简单方法:正则表达式(或非正则表达式)在十进制数字/空格上拆分字符串,应用乘法器,然后重新生成字符串。字符串是由字符而不是数字组成的。您需要解析字符串中的数字,将它们相乘并重新生成字符串。路径中的标志必须为0或1。如果您天真地将所有值乘以2,并且路径中有一个非零的标志,那么该路径将变得无效。对不起,我误读了。试试“8090”,它会变成“1601160”。更换不安全。
d
是SWG路径;因此,解决方案应该接受任何SWG,例如,
“M150 0 L75 200 L225 200 Z”
,对于这些SWG,实现不会使ited的值加倍@dmitrybychenko,并且如果路径的标志值为1,则会使路径无效。“if(isNum)//如果没有”,“在两个以上的数字之间”-“,”就在两个数字之间。你的问题不清楚,这就是我处理所有案件的原因。然后您可以将其简化几步:删除“.TryParse”布尔输出检查,删除结果构建周围的if,删除第一个“else”部分。等等。我只是建议编写代码来帮助你找到如何实现目标的方法,但最终你可以随心所欲……@Zhaph BenDuguid>我看到第一篇文章被编辑了,所以OP想要的现在更清楚了。我删除了不相关的“第一个”建议。我还添加了第二个的简化版本。如果路径的标志值为1,则会使路径无效。请告诉OP;)。我只是回答它的问题。这是返回的双倍列表,而不是它的数字加倍的字符串。如果您愿意,这是作为字符串的结果;-)结果与OP想要的完全不同。如果路径的标志值为1,则该路径无效。您的解决方案非常简单。但是它对大于99的数字不起作用。@CPA它确实起作用。例如:对于字符串“M 0,20 110,20 40,80 0,80 z”,它返回“M 0,40 220,40 81,60 1,60 z”。您要传递给函数的字符串是什么?如果路径的标志值为1,这将使路径无效。@Maco抱歉,我的解释不清楚。“0,20”-有两个数字,而不是一个逗号分隔的数字。