我如何只解析字符串中的数字?

时间:2017-06-03 19:27:52

标签: c# unity3d unity5

我希望在transform属性下的Rect.rectangles中使用字符串“matrix(0.87142591,0.49052715,-0.49052715,0.87142591,0,0)”来获得2个属性,如transform和transform1,每个属性都有一个例如:变换“0.12345678”          transform1“1.12345678”

private void Parse()
    {
        XDocument document = XDocument.Load(@"C:\Users\mysvg\Documents\my.svg");

        Rect.rectangles = document.Descendants().Where(x => x.Name.LocalName == "rect").Select(x => new Rect()
        {
            style = Rect.GetStyle((string)x.Attribute("style")),
            id = (string)x.Attribute("id"),
            width = (double)x.Attribute("width"),
            height = (double)x.Attribute("width"),
            x = (double?)x.Attribute("width"),
            y = (double?)x.Attribute("width"),
            transform = x.Attribute("transform".Substring(18, 43)) == null ? "" : (string)x.Attribute("transform".Substring(18, 43))
        }).ToList();
    }

和Rect类:

public class Rect
    {
        public static List<Rect> rectangles { get; set; }
        public Dictionary<string, string> style { get; set; }
        public string id { get; set; }
        public double width { get; set; }
        public double height { get; set; }
        public double? x { get; set; }
        public double? y { get; set; }
        public string transform { get; set; }

        public static Dictionary<string, string> GetStyle(string styles)
        {
            string pattern = @"(?'name'[^:]+):(?'value'.*)";
            string[] splitArray = styles.Split(new char[] { ';' });
            Dictionary<string, string> style = splitArray.Select(x => Regex.Match(x, pattern))
                .GroupBy(x => x.Groups["name"].Value, y => y.Groups["value"].Value)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());
            return style;
        }
    }

我正在尝试使用子字符串但超出范围异常。

ArgumentOutOfRangeException:不能超过字符串的长度

在线:

transform = x.Attribute("transform".Substring(18, 43)) == null ? "" : (string)x.Attribute("transform".Substring(18, 43))

字符串是:

  

变换= “矩阵(0.40438612,-0.91458836,0.92071162,0.39024365,0,0)”

我想只得到前两个数字:0.40438612,-0.91458836

更新

我发现了一种使用foreach的方法:

private void Parse()
    {
        XDocument document = XDocument.Load(@"C:\Users\mysvg\Documents\my.svg");

        Rect.rectangles = document.Descendants().Where(x => x.Name.LocalName == "rect").Select(x => new Rect()
        {
            style = Rect.GetStyle((string)x.Attribute("style")),
            id = (string)x.Attribute("id"),
            width = (double)x.Attribute("width"),
            height = (double)x.Attribute("width"),
            x = (double?)x.Attribute("width"),
            y = (double?)x.Attribute("width"),
            transform = x.Attribute("transform") == null ? "" : (string)x.Attribute("transform")
        }).ToList();
        string t = null;
        foreach(Rect rect in Rect.rectangles)
        {
            if (rect.transform != null && rect.transform != "")
            {
                t = rect.transform.Substring(7, 21);
            }
        }
    }

但我不希望在新的Rect()之后这样做{ 我想在线上进行前两个数字提取:

transform = x.Attribute("transform") == null ? "" : (string)x.Attribute("transform")

原因是我在代码的底部有一个类:

public class Rect
    {
        public static List<Rect> rectangles { get; set; }
        public Dictionary<string, string> style { get; set; }
        public string id { get; set; }
        public double width { get; set; }
        public double height { get; set; }
        public double? x { get; set; }
        public double? y { get; set; }
        public string transform { get; set; }

        public static Dictionary<string, string> GetStyle(string styles)
        {
            string pattern = @"(?'name'[^:]+):(?'value'.*)";
            string[] splitArray = styles.Split(new char[] { ';' });
            Dictionary<string, string> style = splitArray.Select(x => Regex.Match(x, pattern))
                .GroupBy(x => x.Groups["name"].Value, y => y.Groups["value"].Value)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());
            return style;
        }
    }

我希望属性转换为保持/包含两个数字。

另一个小问题如何提取前两个数字,例如,如果其中一个数字在开始时有 - (减号),例如,如果transform包含字符串:“matrix(0.40438612,-0.91458836,0.92071162,0.39024365, 0,0)“

如果两个数字中的一个在开头有负数,或者两个数字在开始时都有负数,则子串(7,21)将不起作用。我需要以某种方式获得前两个数字。但主要问题是如何直接从属性中提取数字。

4 个答案:

答案 0 :(得分:2)

您是否正在寻找正则表达式

 using System.Globalization;
 using System.Linq;
 using System.Text.RegularExpressions;

 ... 

 string transform = "matrix(0.40438612,-0.91458836,0.92071162,0.39024365,0,0)";

 double[] result = Regex
   .Matches(transform, @"-?[0-9]*\.?[0-9]+")
   .OfType<Match>()
   .Take(2)
   .Select(match => double.Parse(match.Value, CultureInfo.InvariantCulture))
   .ToArray(); 

答案 1 :(得分:1)

如果没有正则表达式,您可以在第一个括号后面获取字符串的一部分,然后使用逗号将其拆分:

var transform="matrix(0.40438612,-0.91458836,0.92071162,0.39024365,0,0)";
var numbers  = transform.Substring(transform.IndexOf('(') + 1).Split(',');
Console.WriteLine(double.Parse(numbers[0]));
Console.WriteLine(double.Parse(numbers[1]));

请添加错误处理。

<== Fiddle Me ==>

答案 2 :(得分:0)

解决方案:

private void Parse()
    {
        XDocument document = XDocument.Load(@"C:\Users\mysvg\Documents\my.svg");

        Rect.rectangles = document.Descendants().Where(x => x.Name.LocalName == "rect").Select(x => new Rect()
        {
            style = Rect.GetStyle((string)x.Attribute("style")),
            id = (string)x.Attribute("id"),
            width = (double)x.Attribute("width"),
            height = (double)x.Attribute("width"),
            x = (double?)x.Attribute("width"),
            y = (double?)x.Attribute("width"),
            transform = x.Attribute("transform") == null ? "" : (string)x.Attribute("transform")
        }).ToList();

        for(int i = 0; i < Rect.rectangles.Count; i++)
        {
            if (Rect.rectangles[i].transform != null && Rect.rectangles[i].transform != "")
            {
                Rect.rectangles[i].transform = Rect.rectangles[i].transform.Substring(7, 21);
            }
        }
     }

答案 3 :(得分:0)

这是最好的答案

UIView2