Replacing values mid-string

2019-09-11 10:13发布

问题:

EXPLANATION OF THE CODE BELOW:

  • I am loading a .txt file and creating a list to store it in.
  • The while loop stores all of the text into the list.
  • I create 3 more lists to store different values.
  • I use REGEX to match for numbers looking like "111.111".
  • If it is a match in the line, group it as "X" and "Y".
  • Add each of the grouped items to the new lists created above (the 3 of them).
  • Use addition on the "X" and "Y" values using a TextBox input value.
  • Output the StringBuilder values to RichTextBoxes.

    private void calculateXAndYPlacement()
    {s
        // Reads the lines in the file to format.
        var fileReader = File.OpenText(filePath + "\\Calculating X,Y File.txt");
    
        // Creates a list for the lines to be stored in.
        var fileList = new List<string>();
    
        // Adds each line in the file to the list.
        var fileLines = "";                                       #UPDATED @Corey Ogburn
        while ((fileLines = fileReader.ReadLine()) != null)       #UPDATED @Corey Ogburn
            fileList.Add(fileLines);                              #UPDATED @Corey Ogburn
    
        // Creates new lists to hold certain matches for each list.
        var xyResult = new List<string>();
        var xResult = new List<string>();
        var yResult = new List<string>();
    
        // Iterate over each line in the file and extract the x and y values
        fileList.ForEach(line =>
        {
            Match xyMatch = Regex.Match(line, @"(?<x>-?\d+\.\d+)\s+(?<y>-?\d+\.\d+)");
            if (xyMatch.Success)
            {
                // Grab the x and y values from the regular expression match
                String xValue = xyMatch.Groups["x"].Value;
                String yValue = xyMatch.Groups["y"].Value;
    
                // Add these two values, separated by a space, to the "xyResult" list.
                xyResult.Add(String.Join(" ", new[]{ xValue, yValue }));
    
                // Add the results to the lists.
                xResult.Add(xValue);
                yResult.Add(yValue);
    
                // Calculate the X & Y values (including the x & y displacements)
                double doubleX = double.Parse(xValue);
                double doubleXValue = double.Parse(xDisplacementTextBox.Text);
                StringBuilder sbX = new StringBuilder();
    
                sbX.AppendLine((doubleX + doubleXValue).ToString());
    
                double doubleY = double.Parse(yValue);
                double doubleYValue = double.Parse(yDisplacementTextBox.Text);
                StringBuilder sbY = new StringBuilder();
    
                sbY.AppendLine((doubleY + doubleYValue).ToString());
    
                calculatedXRichTextBox.AppendText(sbX + "\n");
                calculatedYRichTextBox.AppendText(sbY + "\n");
            }
        });
    }
    

NOW::: What I am trying to do is take these new values that are in the calculatedXRichTextBox and calculatedYRichTextBox and Replace the old values (in the fileList) and output them to override the calculatedXRichTextBox and calculatedYRichTextBox.

SO, the values I have are:

(original file)

TEXT   TEXT  227.905  203.244  180  
TEXT   TEXT  242.210  181.294  180  
TEXT   TEXT  236.135  198.644  90  

(stripped values "X" and "Y" -- in 2 different lists)

227.905                      203.244  
242.210                      181.294  
236.135                      198.644  

(calculated value adding "10" to "X" and "20" to "Y" -- placing them into 2 different RichTextBoxes)

237.905                      223.244
252.210                      201.294
246.135                      218.644

(THIS IS WHAT I WANT TO END UP WITH -- the original file + calculated values replacing old values)

TEXT   TEXT  237.905  223.244  180  
TEXT   TEXT  252.210  201.294  180  
TEXT   TEXT  246.135  218.644  90  

QUESTIONS:

  • How can I do this?

回答1:

Another way to approach your problem is to think of your code as applying a transformation to a stream of data.

That's basically what the sample below does. It was written for .NET 4.0, if you are targeting an earlier runtime you'll have to use the ReadAllLines method (as opposed to ReadLines) and instead of using a Tuple you'll need to make a container class (which can be private to this class) to return multiple values from your function.

void calculateXAndYPlacement()
{
    // Read data from file
    var path = @"[path to your document]";
    var data = File.ReadLines(path + "data.txt");

    // Parse the values you'll be modifying your data by
    var doubleXValue = double.Parse(xDisplacementTextBox.Text);
    var doubleYValue = double.Parse(yDisplacementTextBox.Text);                     

    // apply your transformation to all valid lines of data
    var modifiedData = from line in data
                       where LineIsValid( line )
                       select ModifyLine( line, doubleXValue, doubleYValue );

    // Do what you wish with the data
    foreach( var dataPoint in modifiedData )
    {
         // grab the values from the Tuple and put them into the
         // appropriate text boxes.
    }
}

Tuple<string,double,double> ModifyLine(string data, double xValue, double yValue)
{
    // split line into parts
    var columns = Regex.Split(data, @"\s+");
    columns.Dump();
    // do your math on each part, I just assigned the new values
    // for the sake of the example.
    columns[3] = xValue.ToString();
    columns[4] = yValue.ToString();

    // recombine the line
    return Tuple.Create( string.Join(" ", columns), xValue, yValue );
}

bool LineIsValid(string lineData)
{
    return Regex.IsMatch(lineData, @"(?<x>-?\d+\.\d+)\s+(?<y>-?\d+\.\d+)");
}


回答2:

Well as you are already using Regex to match your values why dont you try using Regex.Replace to change them.

See this link for more information...

http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.replace(v=vs.71).aspx



回答3:

Try string.Replace like in this PSEUDO code:

int i=0;
while(newline){
   if(patternMatch){
      // replace old values with new ones
      line.Replace(oldXList[i], newXList[i]).Replace(oldYList[i], newYList[i]);
      i++;
   }
}

It is not very elegant but should work, right?