2011-08-15 107 views
0

我解析HTML文档..和我终于到哪里,我需要检查可能含有符号(1或多个)线的Perl /正则表达式来检查公司符号

AAPL,GOOG,MSFT
AAPL
GE
GE,NVDA,IBM,CRM

正如你所看到的线条可以CONTA在一个或多个符号(由逗号分隔)..如何检查线路以检查是否符合上述标准? (即,检查一个或多个符号是否在该特定线正被处理)

我的在它的第一刺 - 这似乎不工作(因为所有的符号的线通常低于20个字符).. if($checkforcompanysymbol =~ m/^[a-z0-9]{0,20}$?/)

+0

如何从任何其他文字破译的象征? – vol7ron

+0

一个符号可以是1个字符(例如C)或最多4个(例如NSWA) – simbatish

+0

由于我在stema评论中的所有理由,我认为你应该考虑改变选定的答案。 – vol7ron

回答

1

试试这个

^[A-Z]{1,4}(?:,\s?[A-Z]{1,4})*$ 

看到它online here on Regexr

^字符串

[A-Z]字符类的开始匹配,从范围匹配任何字符AZ

[A-Z]{1,4}比赛1来自角色类别

的4个字符

(?:,\s?[A-Z]{1,4})*(?: ...)是一个非捕获组,,\s?是一个逗号,后跟一个可选空白,1-4个字符,所有这0次或更多次(因为*)。

$字符串

+0

工作就像一个魅力,非常好..谢谢 – simbatish

+0

**这不会工作** if (例如'APPL-GOOG-MSFT','APPL | GOOG | MSFT')或***不同情况***(例如'appl,goog,msft')或者*** ***没有逗号***(例如'APPL GOOG MSFT')或分隔符前的***空格***(例如'APPL,GOOG,MSFT')或开头的***空格*** (例如'APPL,GOOG,...') – vol7ron

+0

@ vol7ron,当然你是对的,这不适用于不同的分隔符**但是OP定义了分隔符是逗号**小有效点是领先的空间,但这将是一个非常简单的方法修复这个问题。 – stema

0

不知道你的$?做底,但你可以尝试:

m/\b\w{1,4}\b/ 

m/\b[a-zA-Z]{1,4}\b/ 

貌似it works for me

while (<DATA>){ 
    print "$..\t$_"; 

    my @matches = (/\b([a-zA-Z]{1,4})\b/g);  # can use \w instead of [a-zA-Z] 

    if (scalar(@matches)){ 
     print "\tMatched: [" 
      , join("\|" , @matches) 
      , "]\n\n" 
    } 
} 

__DATA__ 
A 
B 
C 
AAPL, GOOG, MSFT 
AAPL 
GE 
GE, NVDA, IBM, CRM 
X 
Y 
Z 
FOOBAR  
('GE, MSFT') 
+0

不工作,不知道为什么..这里是一个字符串示例('GE,MSFT')..但你的正则表达式不会返回true :( – simbatish

+0

你确定吗?它适用于我,[见示例](http ://codepad.org/vPcrBSju)我甚至使用了相同的确切字符串,并使用了'FOOBAR'作为一个太长的情况 – vol7ron

1

(1)正在使用[A-Z0-9]字符类,它是小写字母和数字0-9。公司的符号是大写的。您可能想要使用[A-Z0-9]。

(2)您的量词意味着至少次,但不超过20次。什么公司名称有0长度?您可能想要使用{1,20}(或更好地表征公司名称的其他数字)。

(3)我不确定您提供的正则表达式是否足以描述公司符号的特征?例如,假设你考虑了(1)和(2),并且使用[A-Z0-9] {1,20}将匹配NOTACOMPANY,除非我错了。如果是我,我只需要列出所有需要检查的公司名单。

(4)您的正则表达式似乎不考虑逗号。

0

使用CSV模块可能是矫枉过正该数据集的末尾匹配,但这里有一个办法做到这一点。增加了一个有点矫枉过正分类和计数,以及,为了好玩:

代码:

use strict; 
use warnings; 
use Text::CSV_XS; 

my $csv = Text::CSV_XS->new({ 
    allow_whitespace => 1, 
}); 

my @list; 
while (my $row = $csv->getline(*DATA)) { 
    for (@$row) { 
     push @list, $_ if /^\w{1,4}$/; 
    } 
} 

my %count; 
for (@list) { 
    $count{$_}++; 
} 

for (sort { $count{$b} <=> $count{$a} || $a cmp $b } keys %count) { 
    printf "%-6s %-3s\n", $_, $count{$_}; 
} 

__DATA__ 
A 
B 
some random line messing regexes up 
,, 
C 
AAPL, GOOG, MSFT 
AAPL 
GE 
GE, NVDA, IBM, CRM 
X 

输出:

AAPL 2 
GE  2 
A  1 
B  1 
C  1 
CRM 1 
GOOG 1 
IBM 1 
MSFT 1 
NVDA 1 
X  1 
Y  1 
Z  1