编辑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列表
答案 0 :(得分:1)
使用以下正则表达式匹配8
或13
位数。 \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
([Ee][Aa][Nn])?
将不区分大小写的序列EAN分组,并使其成为?
的可选项
[_]?
使下划线成为可选项。我为方便起见添加了方括号[0-9]{13}
和[0-9]{8}
\b( ... )\b
块中以识别单词边界|
以下是来自http://regexpal.com/的屏幕截图,其中显示了测试集和匹配项。
乔治,我必须说我不喜欢重复代码,(或其他任何事情:D)。因此,我不太喜欢整个
([Ee][Aa][Nn])?[_]?
出现两次。此外,如果明天你想寻找EAN5,你必须进一步复制它,正则表达式变得更加难看。
以下是清理前的内容:
\b(([Ee][Aa][Nn])?[_]?[0-9]{13}|([Ee][Aa][Nn])?[_]?[0-9]{8})\b
以下是来自http://regexpal.com/的屏幕截图,其中显示了测试集和匹配项。