Closed KristofferStrube closed 2 years ago
I googled this : keyword regex to replace decimal point "without zero"
Went to this
Then played with the stackoverflow answer from Andreas with https://regex101.com/r/7ymqcn/1
Then finally https://dotnetfiddle.net/
using System;
using System.Drawing;
using System.Drawing.Imaging;
using Svg;
using System.Xml;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
string pattern = @"(?:0|.[1-9][0-9]*)(:\.[0-9]{1,2})?";
string replacement = " 0$0";
string input = "a.457.318.914.317.61.78";
string result = Regex.Replace(input, pattern, replacement);
Console.WriteLine(result);
}
}
Output is a 0.457 0.318 0.914 0.317 0.61 0.78
I will add this after I have tested its validity and create a test case that covers this.
This has been added now and tested
I wrongly only tested that my new test parsed but this fix did actually break a lot of existing tests. An example is:
string pattern = @"(?:0|.[1-9][0-9]*)(:\.[0-9]{1,2})?";
string replacement = " 0$0";
string input = "M 10 10 A 1 1 0 1 1 20 30";
string result = Regex.Replace(input, pattern, replacement);
Console.WriteLine(result);
Hi Kristoffer,
The case complexity is due to non separation between numbers even with a simple space in :
"a.457.318.914.317.61.78";
Maybe you need two passes : one which replace 0.98 into .98 then second pass which does the opposite
Could you try passing your tests serie with this Expression :
(?:[0]?.[1-9][0-9]*)(:.[0-9]{1,2})? Here are my tests which work in the 3 cases but with two passes
M 10 10 A 1 1 0 1 1 20 30 a 0.457 0.318 0.914 0.317 0.61 0.78 a .457 .318 .914 .317 .61 .78 a.457.318.914.317.61.78
First of all thanks for sharing this project, very interesting for me to learn SVG handling in Blazor.
I'm not a RegEx expert so there may be an easier way to do this. But the following worked for me.
In PathData.cs added a new method:
// Correct strings like "l-.004.007" and "c0-.57.464"
private static string ValidateString(string seq)
{
var tokens = seq.Split(' ');
for (int i = 0; i < tokens.Length; i++)
{
int numberOfPeriods = tokens[i].Count(f => (f == '.'));
if (numberOfPeriods > 1)
{
int startIndex = tokens[i].IndexOf('.') + 1;
for (int j = 1; j < numberOfPeriods; j++)
{
int index = tokens[i].IndexOf('.', startIndex);
tokens[i] = tokens[i].Insert(index, " 0");
startIndex = index + 3;
}
}
}
return string.Join(" ", tokens);
}
Then changed line 21 to:
var seq = ValidateString(splitInstructionSequences[curr].TrimEnd(' '));
Successfully tried this fix with a bunch of SVGs that were failing from https://simpleicons.org/
Enrique
Hey Enrique (@ercgeek),
Glad to hear that you enjoy the project.
Thanks for the help. I have added your function and tested that it works.
Your solution is nice and easy to understand but I have left a comment above it that we maybe should look at more performant methods in the future.
Again thanks.
Sometimes we get input like this for some instructions in path data:
Which should be made into:
The idea would be to find all places where there is a
.
char with either an alphabetic char before or numbers that continue until another.
without any spaces.I tried doing something like this.
but that result is:
So I need to match on [a-zA-Z] optionally and I need somehow to match dots twice and fix some extra
.
´s.One could also take a look at the implementation details for Path data: https://www.w3.org/TR/SVG/paths.html#PathDataBNF where they have written a full parse three in BNF that could potentially capture all of this without any edge cases like this.
But for this second approach, we need to redo the full parsing which will potentially make it tougher to read.