2009-08-18 407 views
11

我不得不清除一些来自OCR的输入,它将手写识别为乱码。任何建议正则表达式来清理随机字符?例如:正则表达式来代替乱码


 
Federal prosecutors on Monday charged a Miami man with the largest 
case of credit and debit card data theft ever in the United States, 
accusing the one-time government informant of swiping 130 million 
accounts on top of 40 million he stole previously. 

, ':, Ie 
':... 11'1 
. '(.. ~!' ': f I I 
. " .' I ~ 
I' ,11 l 
I I I ~ \ :' ,! .~ , .. r, 1 , ~ I . I' , .' I ,. 
, i 
I ; J . I.' ,.\) .. 
. : I 
'I', I 
.' ' 
r," 

Gonzalez is a former informant for the U.S. Secret Service who helped 
the agency hunt hackers, authorities say. The agency later found out that 
he had also been working with criminals and feeding them information 
on ongoing investigations, even warning off at least one individual, 
according to authorities. 

eh....l 
~.\O ::t 
e;~~~ 
s: ~ ~. 0 
qs c::; ~ g 
o t/J (Ii ., 
::3 (1l Il:l 
~ cil~ 0 2: 
t:lHj~(1l 
. ~ ~a 
0~ ~ S' 
N ("b t/J :s 
Ot/JIl:l"-<:! 
v'g::!t:O 
-....c...... 
VI (:ll <' 0 
:= - ~ 
< (1l ::3 
(1l ~ ' 
t/J VJ ~ 
Pl 
..... 
.... 
(II 
+3

+1,因为它是一个有趣的问题,虽然我怀疑你不会得到其问题的解答。 – 2009-08-18 03:40:03

+0

这是一个很好的问题,而单词/短语识别(或其他方式)是AI的一个热门话题。 – Russell 2009-08-18 03:41:50

+1

我强烈地感到REGEX是这项工作的错误工具。 – Breton 2009-08-18 05:20:00

回答

0

好一组符号将匹配位乱码。也许检查字典的话?

似乎有很多换行符都是乱码,所以也可能是一个指标。

+0

几年前,我在Uni做了一些关于短语提取的研究(你有相反的做法)。有很多论文(例如http://portal.acm.org/citation.cfm?id=1097059),但不幸的是没有单一的“全部”解决方案。 – Russell 2009-08-18 03:43:19

0

有趣的问题。

如果这是有代表性的,我想你可以建立一个常用词库并删除任何与它们不匹配的行。

或者也许你可以匹配字符和标点符号,看看是否有可靠的比例截止点,或者只是某些字符出现的频率将其标记为乱码。

无论如何,我认为必须有一些编程逻辑,而不仅仅是一个单一的正则表达式。

0

我想这个正则表达式在这里没有帮助。正则表达式基本上会匹配确定性输入,即正则表达式将有一组预定义的模式匹配。在大多数情况下,乱码会是随机的。 一种方法是颠倒问题,即匹配相关文本而不是匹配乱码。

1

其中simpleset溶液(不涉及regexpes)的:

#pseudopython

number_of_punct =总和([1,如果c.ispunct()否则为0用于线c])

如果number_of_punct> len(line)/ 2:line_is_garbage()

好。或粗鲁的正则表达式s/[!,'“@#〜$%^ &] {5,} // g

+0

这条线怎么样:,我 – Breton 2009-08-18 05:30:33

+0

什么都没有。稍后用手取出。不要指望启发式方法去除所有的垃圾。当天的谚语:“不要把婴儿用洗澡水扔掉”。 – maykeye 2009-08-18 07:34:10

1

正则表达式在这里没有帮助,我想说,如果您控制了识别部分,在那里更好的质量: http://www.neurogy.com/ocrpreproc.html

你也可以让用户来帮助你,并指定你使用的文本类型,例如,如果它是一本书的页面,那么你会希望大多数行是相同的长度和主要由字母,空格和标点组成。

0

我会声称一个正则表达式,比如“除了空格之外的任何标点符号都是垃圾邮件”。

所以在.NET中它可能像

.Replace("\\p{1,}[a-zA-Z0-9]{1,}", ""); 

然后你会考虑“任何单词有两个或更多的连续标点符号:

.Replace(" \\p{2,} ", ""); 

似乎是一个良好的开端反正。

+0

>我认为这样的正则表达式类似于“任何标点符号,除了空格之外都是垃圾邮件” 不尽然,有些姓氏有连字符,不仅姓氏(不要忘记我),还有“引号“以标点符号开头 – maykeye 2009-08-18 04:23:43

+0

正确;然后不要在正则表达式的那一部分包含双引号,我不认为他正在寻找一个万无一失的系统;只是要做一次'第一次剪辑' – 2009-08-18 04:26:09

+0

我不同意。 ... :-) – 2009-08-18 15:29:36

2

一种简单的规则,类似于anonymous答案:

listA = [0,1,2..9, a,b,c..z, A,B,C,..Z , ...] // alphanumerical symbols 
listB = [[email protected]$%^&...] // other symbols 

Na = number_of_alphanumeric_symbols(line) 
Nb = number_of_other_symbols(line) 

if Na/Nb <= garbage_ratio then 
    // garbage 
+0

这假设整条线是垃圾或不是,但基于样本,这是一个合理的假设。 – 2009-08-18 05:28:25

+0

是的,它用于过滤出整条线。与*正常*文本不会那么简单:-) – 2009-08-18 06:19:12

2

不知道它会如何工作,但我认为在过去的这个问题,袖手旁观。我曾经有时玩过一个小编程设备,名为markov chain

现在维基百科的文章可能没有什么意义,除非你看到马尔可夫链有用的其他一些东西。马尔科夫链的一个实例是Greeking generator。另一个例子是MegaHAL chatbot.

希腊文是看起来像单词的胡言乱语。马尔可夫链提供了一种随机生成字母序列的方式,但是对随机选择进行加权以模拟所检查的语料库的频率模式。例如,考虑到字母“T”,字母h比任何其他字母更可能出现。因此,您可以检查一个语料库(比如某些报纸或博客文章),以生成您所定位语言的指纹。

现在您已经有了频率表/指纹,您可以检查您的示例文本,并根据出现的可能性对每个字母进行评分。然后,您可以将这些字母标记在特定阈值下,以便删除。换句话说,一个惊喜过滤器。过滤出惊喜。

如何生成频率表有一些余地。你并不局限于另一封信。您可以建立一个频率表,预测每个有向图(两个字母组)或每个三角形或四边形后面可能出现哪个字母。给出一些以前的文本,你可以在另一边工作,预测可能和不可能的三字母出现在某些位置。

它有点像模糊正则表达式。根据与参考文本的相似程度,整个文本将以滑动比例进行评分,而不是MATCH或NO MATCH。

1

我做了一个消除不包含至少两个3个字母单词或一个6个字母单词的行的组合。

([AZ | AZ] {3,} \ S){2,} |(即[az | AZ] {6})

http://www.regexpal.com/

+0

我会添加一个字典比较,以确保它找到的单词是真实的,而不只是随机字母。 – 2009-08-19 14:38:42

0

我喜欢@布雷顿的答案 - 我d建议使用他的语料库方法还使用已知的“坏扫描”库,这可能更容易识别,因为如果错误的OCR扫描来自“垃圾”,它比“好文本”更具内部一致性(不同字形的数目是例如较低)。

0

另一个好方法是使用拼写检查器/字典,并在用正则表达式消除了不可读的东西后查找'单词'。

1

这里是一个Perl实现garbage_ratio启发的:

#!/usr/bin/perl 

use strict; 
use warnings; 

while (defined(my $chunk = read_chunk(\*DATA))) { 
    next unless length $chunk; 

    my @tokens = split ' ', $chunk; 
    # what is a word? 
    my @words = grep { 
     /^[A-Za-z]{2,}[.,]?$/ 
      or /^[0-9]+$/ 
      or /^a|I$/ 
      or /^(?:[A-Z][.])+$/ 
    } @tokens; 

    # completely arbitrary threshold 
    my $score = @words/@tokens; 
    print $chunk, "\n" if $score > 0.5; 
} 

sub read_chunk { 
    my ($fh) = @_; 
    my ($chunk, $line); 

    while (my $line = <$fh>) { 
     if($line =~ /\S/) { 
      $chunk .= $line; 
      last; 
     } 
    } 

    while (1) { 
     $line = <$fh>; 
     last unless (defined $line) and ($line =~ /\S/); 
     $chunk .= $line; 
    } 

    return $chunk; 
} 


__DATA__ 

粘贴文本上面上述__DATA__后(这里不重复的文字,以节省空间)。当然,使用__DATA__部分是为了发布自包含脚本。在现实生活中,你将有代码打开文件等。

输出:

 
Federal prosecutors on Monday charged a Miami man with the largest 
case of credit and debit card data theft ever in the United States, 
accusing the one-time government informant of swiping 130 million 
accounts on top of 40 million he stole previously. 

Gonzalez is a former informant for the U.S. Secret Service who helped 
the agency hunt hackers, authorities say. The agency later found out that 
he had also been working with criminals and feeding them information 
on ongoing investigations, even warning off at least one individual, 
according to authorities.