繁体   English   中英

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

[英]How can i parse only the numbers from the string?

我希望在transform属性下的Rect.rectangles中具有字符串“ matrix(0.87142591,0.49052715,-0.49052715,0.87142591,0,0)”来具有2个属性,例如transform和transform1,并且每个属性都有一个数字:变换“ 0.12345678”变换1“ 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))

字符串是:

transform =“ matrix(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 )”

如果两个数字之一的开头都为负,或者两个数字的开头都为负,则Substring(7,21)将不起作用。 无论如何,我都需要获得前两个数字。 但是主要问题是如何直接从属性中直接提取数字。

您在寻找正则表达式吗?

 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(); 

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

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]));

请添加错误处理。

<==摆弄我==>

解:

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);
            }
        }
     }

这是最好的答案

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            Rect.rectangles = doc.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 ? null : (object)Rect.GetTransform((string)x.Attribute("transform"))
            }).ToList();


        }
    }
    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 object 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;
        }
        public static KeyValuePair<double, double> GetTransform(string matrix)
        {
            string pattern = @"[-+]?\d+\.\d+";
            MatchCollection matches = Regex.Matches(matrix, pattern);
            KeyValuePair<double, double> kp = new KeyValuePair<double, double>(
                double.Parse(matches[0].Value),
                double.Parse(matches[0].Value)
                );

            return kp;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM