在字符串工作的中间不能使8和13位的正则表达式模式

时间:2014-09-17 12:26:16

标签: c# .net regex

编辑2:

是的,就像我想的那样,我需要将模式更改为2个不同的模式,因为OR会匹配13位数字,匹配8位数字

THE SOLUTION IS:
Regex EAN8 = new Regex(@"\b\d{8}\b");
Regex EAN13 = new Regex(@"\d{13}\b");
PS FOR EDIT2:正如有人说的那样,将来我最终会找到EAN1234567890123或EAN_1234567890123,这些模式无法解决,我不知道从哪里开始搜索这样的模式。

我正在做一个项目,我需要从文本中获取多个EAN。 我已经有一个验证类,看看它们是否有效。 我可以拿13位数字(但我认为我使用的模式不正确,迟早会给出问题。

字符串示例:“OL-120 112 82 Estuchado,fácilpeedura。8410032002279 227 24”

你可以看到中间有一个有效的EAN13:“8410032002279” 我正在使用这种模式:

Regex EAN13 = new Regex(@"\d{13}");

它给了我字符串中的EAN,但我认为正确的模式应该是这样的:

Regex EAN13 = new Regex(@"\d{13}$");

但是当我使用它时它不起作用。可能是因为字符串没有结束。

如果我使用这种模式,我对8位数的EAN有类似的问题:

Regex EAN8 = new Regex(@"\d{8}");

它给了我13个数字的eans切成8 ...

如果EAN的位置在字符串中的任何位置,我应该做什么才能使两种模式都起作用;对于8位数字,只返回8位数字的真实字符串而不是8位数字的实际字符串。

提前致谢

编辑:进一步的代码,以了解我在做什么

Regex EAN = new Regex(@"\b(?:\d{8}|\d{13})\b");
using (StreamReader sr = new StreamReader(@"....txt"))
        {
            string currentLine;
            while ((currentLine = sr.ReadLine()) != null)
            {
                Match m13 = EAN.Match(currentLine);
                Match m8 = EAN.Match(currentLine);

                if (m8.Success)
                {
                    lista_EAN8.Add(m8.Value);
                    //string valido8 = new Ean8Validate().ValidateEan8(m8.Value);
                    //if (valido8 == m8.Value)
                    //{
                    //    lista_EAN8.Add(m8.Value);
                    //} 
                }

                if (m13.Success)
                {
                    string valido13 = new Ean13Validate().ValidateEan13(m13.Value);
                    if (valido13 == m13.Value)
                    {
                        lista_EAN13.Add(m13.Value);
                    }
                }
            }
        }

像这样,它返回13个数字eans列表中的相同值和8个数字eans列表

5 个答案:

答案 0 :(得分:1)

使用以下正则表达式匹配813位数。 \b是一个在单词字符和非单词字符之间匹配的单词边界。因此,它避免匹配13位数字中的8位数字。

\b(?:\d{8}|\d{13})\b

答案 1 :(得分:1)

好看,你想要2个不同的正则表达式,仅用于定位8位数匹配,另一个用于定位13位数匹配

用于匹配8位EAN的使用;

\b(?:\d{8})\b

用于匹配和13位EAN使用;

\b(?:\d{13})\b

另外你想要一个你可以使用的EAN(大写或小写)的选项前缀;

为8位

\b(?:[Ee][Aa][Nn])?(?:\d{8})\b

为13位

\b(?:[Ee][Aa][Nn])?(?:\d{8})\b

对于您的示例,您要修改代码,使其读取此类内容。

Regex EAN8 = new Regex(@"\b(?:\d{8})\b");
Regex EAN13 = new Regex(@"\b(?:\d{13})\b");
using (StreamReader sr = new StreamReader(@"....txt"))
    {
        string currentLine;
        while ((currentLine = sr.ReadLine()) != null)
        {
            Match m13 = EAN13.Match(currentLine);
            Match m8 = EAN8.Match(currentLine);

            if (m8.Success)
            {
                lista_EAN8.Add(m8.Value);
            }

            if (m13.Success)
            {
                lista_EAN13.Add(m13.Value);
            }
        }
    }

现在,如果我们稍微调整正则表达式,我们可以从EAN数字中提取数字部分,即使它们以EAN *或EAN _ *为前缀

Regex EAN8 = new Regex(@"\b(?:[Ee][Aa][Nn]_?)?(\d{8})\b");
Regex EAN13 = new Regex(@"\b(?:[Ee][Aa][Nn]_?)?(\d{13})\b");
using (StreamReader sr = new StreamReader(@"....txt"))
    {
        string currentLine;
        while ((currentLine = sr.ReadLine()) != null)
        {
            Match m13 = EAN13.Match(currentLine);
            Match m8 = EAN8.Match(currentLine);

            if (m8.Success)
            {
                lista_EAN8.Add(m8.Groups[1].Value);
            }

            if (m13.Success)
            {
                lista_EAN13.Add(m13.Groups[1].Value);
            }
        }
    }

这将捕获数字部分,同时丢弃EAN前缀

答案 2 :(得分:0)

试试这个正则表达式字符串。 \b =字边界,|确保它只匹配8或13而不是之间的某个数字:

\b\d{8}\b|\b\d{13}\b

答案 3 :(得分:0)

如果你想不允许unicode数字使用字符类而不是快捷键\ d(它更快)

\b(?:[0-9]{8}|[0-9]{13})\b

答案 4 :(得分:0)

我成功地编造了这个:

\b(([Ee][Aa][Nn])?[_]?([0-9]{13}|[0-9]{8}))\b
  1. 此部分([Ee][Aa][Nn])?将不区分大小写的序列EAN分组,并使其成为?的可选项
    1. 然后[_]?使下划线成为可选项。我为方便起见添加了方括号
    2. 使用字符代表[0-9]{13}[0-9]{8}
    3. 标识数字
    4. 所有内容都包含在\b( ... )\b块中以识别单词边界
    5. 两个EAN类型由括号括起,并以OR |
    6. 分隔
  2. 以下是来自http://regexpal.com/的屏幕截图,其中显示了测试集和匹配项。

    Screenshot from regexpal.com showing the testing set and the matching.

    乔治,我必须说我不喜欢重复代码,(或其他任何事情:D)。因此,我不太喜欢整个([Ee][Aa][Nn])?[_]?出现两次。此外,如果明天你想寻找EAN5,你必须进一步复制它,正则表达式变得更加难看。


    以下是清理前的内容:

    \b(([Ee][Aa][Nn])?[_]?[0-9]{13}|([Ee][Aa][Nn])?[_]?[0-9]{8})\b
    

    以下是来自http://regexpal.com/的屏幕截图,其中显示了测试集和匹配项。

    Screenshot from regexpal.com showing the testing set and the matching.