2009-08-18 104 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.