2017-06-01 202 views
0

我通常从一个巨大的列表中提取戴尔服务标签,我有一段代码应该提取7个Alpha-Numeric标签,但如果文档中有额外的文本,它会有时会提取额外的文本。正则表达式匹配超过{7}

我的模式:

Regex rServTag_Pattern = new Regex(@".*(?=.{7})(?=.*\d)(?=.*[a-zA-Z]).*"); 
var mTag = rServTag_Pattern.Match(Clipboard.GetText()); 

对于它真正起作用的大部分,但一段时间后,这很令人讨厌,提取比所需要的更多。我怎样才能确保它只提取7Alpha-数字字符串?

示例服务标签:7DJHT90,LK2JHN4,等等(这些都不是实际的服务标签

+0

你可以发布一些包含服务标签的示例输入吗?给我们一些额外的文本可以帮助我们捕获正确的子串并避免不需要的位。服务标签是否始终只有CAPS和数字? – mickmackusa

回答

0

只需使用

var rServTag = new Regex(@"(?=([a-zA-Z]+\d[a-zA-Z\d]+|\d+[a-zA-Z][a-zA-Z0-9]+))[a-zA-Z0-9]{7}"); 

如果你需要避免提取内文7个字母+数字的组合。 ,您可以添加单词边界:

var rServTag = new Regex(@"\b(?=([a-zA-Z]+\d[a-zA-Z\d]+|\d+[a-zA-Z][a-zA-Z0-9]+))[a-zA-Z0-9]{7}\b"); 
+0

不幸的是,它不起作用,它也匹配单词,而不仅仅是字母数字字符。 http://regexr.com/3g318 – herboren

+0

字母是字母数字字符。我想你的意思是它必须有字母和数字。 – NetMage

+0

@herboren好的,更新我的RE到一些复杂的东西。 – NetMage

0

使用wordboundaries隔离7个字符

Regex rServTag_Pattern = new Regex(@".*\b[A-Z\d]{7}\b.*"); 

这是假设只有在服务标签首都和数字(基于OP的样品输入)

+0

多数民众赞成在可怕的,我刚刚阅读这杯浓咖啡 – herboren

+0

@herboren我不是一个C#编码器。如果我的回答不起作用,我宁愿将其从此页面中删除。你能告诉我它是否适合你的情况吗? – mickmackusa

0

我就拆你的问题分为两个步骤:

  • 分割由分隔符输入
  • 处理每个分割字符串

在你的情况,我会分裂Clipboard.GetText()所有非字母数字的字符:

string[] splitArray = Regex.Split(Clipboard.GetText(), @"[^a-zA-Z\d]+"); 
foreach (string s in splitArray) 
{ 
    // process s 
} 

然后为每个分割字符串s,适用,只有符合其至少有一个字母(?=.*[a-zA-Z]),至少一个数字(?=.*\d)字符串,正好是7个字符长的正则表达式^[a-zA-Z\d]{7}$

new Regex(@"^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d]{7}$"); 

实施例:

Regex regex = new Regex(@"^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d]{7}$"); 
string[] splitArray = Regex.Split(Clipboard.GetText(), @"[^a-zA-Z\d]+"); 
foreach (string s in splitArray) 
{ 
    if (regex.IsMatch(s)) 
    { 
     // s is a valid service tag 
    } 
} 

鉴于INP ut "123ABCD, ABCDEFG... ABCD123, 123AAAAAAAA"splitArray将等于["123ABCD", "ABCDEFG", "ABCD123", "123AAAAAAAA"]

regex.IsMatch(s)对于s"123ABCD""ABCD123"将返回true。