创建具有多个场景的正则表达式的最简单方法

时间:2015-09-02 11:17:32

标签: c# regex

我有功能,我有4个正则表达式场景搜索轮胎宽度..

string sizeWidthRgx = @"(\d{3})[\s\/]\d{2}[\s\/R]?[\s\/]\d{2}";
string sizeWidthRgxSecond = @"(\d{3})[\s\/ZR]?\s?\d{2}";
string sizeWidthRgxThird = @"(\d{2})\s?X?x?\s?\d{1,2}[,.]\d{2}";
string sizeWidthRgxFourth = @"(\d{3})[\s\/]\d{2}[\s\/]?R\d{2}";

var matchSizeWidth = Regex.Match(sizeWidthUpper, sizeWidthRgx);
var matchSizeWidthOther = Regex.Match(sizeWidthUpper, sizeWidthRgxSecond);
var matchSizeWidthThird = Regex.Match(sizeWidthUpper, sizeWidthRgxThird);
var matchSizeWidthFourth = Regex.Match(sizeWidthUpper, sizeWidthRgxFourth);

有人知道如何将所有正则表达式加入到搜索此参数的一种或其他方式。

例如:

(7.50)/80 R16, (305)/35 R24, (31)X10.50R15, (175)/65/14.

多数情况下,我需要从'()'

中获取所有数字

@Edit 这是我的代码:

            var sizeWidthUpper = productName.Trim().ToUpper();

        string sizeWidthRgx = @"(\d{3})[\s\/]\d{2}[\s\/R]?[\s\/]\d{2}"; // 1 scenariusz
        string sizeWidthRgxSecond = @"(\d{3})[\s\/ZR]?\s?\d{2}"; // 2 scenariusz
        string sizeWidthRgxThird = @"(\d{2})\s?X?x?\s?\d{1,2}[,.]\d{2}"; //3 scenariusz, np. BARUM BRAVURIS 4X4 31X10.50R15 109 S FR
        string sizeWidthRgxFourth = @"(\d{3})[\s\/]\d{2}[\s\/]?R\d{2}";

        var matchSizeWidth = Regex.Match(sizeWidthUpper, sizeWidthRgx);
        var matchSizeWidthOther = Regex.Match(sizeWidthUpper, sizeWidthRgxSecond);
        var matchSizeWidthThird = Regex.Match(sizeWidthUpper, sizeWidthRgxThird);
        var matchSizeWidthFourth = Regex.Match(sizeWidthUpper, sizeWidthRgxFourth);

        int outSizeWidth = 0;
        if(matchSizeWidth.Success)
        {
            if (int.TryParse(matchSizeWidth.Groups[1].Value, out outSizeWidth))
            {
                if ((outSizeWidth >= 125) && (outSizeWidth <= 335))
                {
                    if ((outSizeWidth % 5) == 0) return outSizeWidth.ToString();
                }
            }
        }
        if (matchSizeWidthFourth.Success)
        {
            if (int.TryParse(matchSizeWidthFourth.Groups[1].Value, out outSizeWidth))
            {
                if ((outSizeWidth >= 125) && (outSizeWidth <= 335))
                {
                    if ((outSizeWidth % 5) == 0) return outSizeWidth.ToString();
                }
            }
        }
        if(matchSizeWidthOther.Success)
        {
            if (int.TryParse(matchSizeWidthOther.Groups[1].Value, out outSizeWidth))
            {
                if ((outSizeWidth >= 125) && (outSizeWidth <= 335))
                {
                    if ((outSizeWidth % 5) == 0) return outSizeWidth.ToString();
                }
            }
        }
        if(matchSizeWidthThird.Success)
        {
            if (int.TryParse(matchSizeWidthThird.Groups[1].Value, out outSizeWidth))
            {
                if ((outSizeWidth >= 30) && (outSizeWidth <= 37)) return outSizeWidth.ToString();
            }
        }
        return string.Empty;

它有效,但我需要知道可以缩短此代码吗?

3 个答案:

答案 0 :(得分:0)

您可以将每个模式包装在命名组((?<name>...))中,例如:

string sizeWidthRgx = @"(?<width>(\d{3})[\s\/]\d{2}[\s\/R]?[\s\/]\d{2})";

确保为每个子图案指定唯一的名称。然后,您可以将它们全部合并为一个模式,用管道分隔它们:

IEnumerable<Match> matches = Regex.Matches(sizeWidthUpper, sizeWidthRgx + "|" + sizeWidthRgxSecond + "|" + sizeWidthRgxThird + "|" + sizeWidthRgxFourth);

然后你可以遍历匹配并查看每个匹配中是否存在命名组(假设该模式,每个匹配只包含一个组):

string matchSizeWidth = null;
string matchSizeWidthOther = null;
string matchSizeWidthThird = null;
string matchSizeWidthFourth = null;
foreach(Match m in matches)
    {
    Group g = m.Groups("width");
    if(g.Success) matchSizeWidth = g.Value; 
    g = m.Groups("other");
    if(g.Success) matchSizeWidthOther = g.Value; 
    g = m.Groups("third");
    if(g.Success) matchSizeWidthThird = g.Value; 
    g = m.Groups("fourth");
    if(g.Success) matchSizeWidthFourth = g.Value; 
    }

答案 1 :(得分:0)

对于你的观点:

  

多数情况下,我需要从&#39;()&#39;

中获取所有数字

你也可以使用这个正则表达式:

\((\d+(?:\.\d+)?)\)

Demo

要合并所有正则表达式,您可以使用|令牌作为OR条件:

regexpattern1|regexpattern2|regexpattern3

答案 2 :(得分:0)

你可能会把你已经融入的模式结合起来:

\(([0-9.]+)\)[X\/]([0-9.]+)[R\/\s]+([0-9]+)

这将每个数值分成一个组,然后产生三个组。

<强>结果:

7.50/80 R16
305/35 R24
31/10.50 R15
175/65 R14

<强>代码

string s = "(7.50)/80 R16, (305)/35 R24, (31)X10.50R15, (175)/65/14.";
string p = "\\(([0-9.]+)\\)[X\\/]([0-9.]+)[R\\/\\s]+([0-9]+)";

MatchCollection mc = Regex.Matches(s, p);
    foreach (Match m in mc) {
       Console.WriteLine("{0}/{1} R{2}", m.Groups[1], m.Groups[2], m.Groups[3]);
    }

示例

https://regex101.com/r/bF1rH0/1