Регулярное выражение для замены тарабарщины

Мне нужно очистить ввод от 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

Ответ 1

Простой эвристический, похожий на анонимный ответ:

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

Ответ 2

Не знаю, как хорошо это сработает, но я рассматривал эту проблему в прошлом, лениво. В некоторых случаях я играю с небольшим программным устройством, называемым цепочкой марков

Теперь статья wikipedia, вероятно, не будет иметь большого смысла, пока вы не увидите некоторые из других вещей, для которых хорошо подходит цепочка марков. Одним из примеров цепочки марков в действии является греческий генератор. Другим примером является чатбол MegaHAL.

Греческий - это тарабарщина, которая похожа на слова. Марковские цепи обеспечивают способ случайного генерации последовательности букв, но взвешивают случайные выборки, чтобы эмулировать частотные шаблоны исследуемого корпуса. Так, например, учитывая букву "Т", буква h скорее всего появится рядом с любой другой буквой. Итак, вы изучаете корпус (например, некоторые газеты или сообщения в блогах), чтобы создать своего рода отпечаток языка, на который вы нацеливаете.

Теперь, когда у вас есть эта таблица частот/отпечаток пальца, вы можете проверить свой образец текста и оценить каждую букву в соответствии с вероятностью ее появления. Затем вы можете отмечать буквы под определенным порогом, вероятно, для удаления. Другими словами, фильтр сюрпризов. Отфильтруйте сюрпризы.

Есть некоторая свобода за то, как вы генерируете свои таблицы freqency. Вы не ограничены одной буквой за другой. Вы можете создать частотную таблицу, которая предсказывает, какая буква, вероятно, будет следовать за каждым орграфом (группа из двух букв), или каждый триграф, или квадриграф. Вы можете работать с другой стороны, предсказывая вероятные и маловероятные триграфы, появляющиеся в определенных положениях, с учетом предыдущего текста.

Это похоже на нечеткое регулярное выражение. Вместо MATCH или NO MATCH весь текст оценивается по скользящей шкале в соответствии с тем, насколько похож на ваш ссылочный текст.

Ответ 3

Одно из простых решений (не связанных с регулярными выражениями):

#pseudopython

number_of_punct = sum ([1 if c.ispunct() else 0 для c в строке])

если number_of_punct > len (строка)/2: line_is_garbage()

хорошо. Или грубое regexpish s/[!, '"@# ~ $% ^ &] {5}}//g

Ответ 4

Regex здесь не поможет. Я бы сказал, если у вас есть контроль над частью распознавания, тогда сосредоточьтесь на улучшении качества там: http://www.neurogy.com/ocrpreproc.html

Вы также можете попросить пользователя помочь вам и указать тип текста, с которым вы работаете. например если это страница из книги, то вы ожидаете, что большинство линий будут иметь одинаковую длину и в основном состоят из букв, пробелов и знаков препинания.

Ответ 5

Я сделал комбо для устранения строк, которые не содержат по крайней мере двух трехбуквенных слов или одного буквенного слова.

([A-Z | A-Z] {3}\s) {2} | ([A-Z | A-Z] {6})

http://www.regexpal.com/

Ответ 6

Вот реализация 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__ предназначено для публикации автономного script. В реальной жизни у вас будет код для открытия файла и т.д.

Вывод:

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.

Ответ 7

Ну, группа символов будет соответствовать бит тарабарщины. Возможно, проверка на словарь для слов?

Кажется, что много разрывов строк, где тарабарщина, так что это может быть и индикатор.

Ответ 8

Интересная проблема.

Если это репрезентативно, я полагаю, вы могли бы создать библиотеку общих слов и удалить любую строку, которая не соответствует ни одному из них.

Или, может быть, вы можете сопоставить символы символов и знаков препинания и посмотреть, есть ли надежное соотношение, или просто частота появления некоторых символов, которые обозначают его как тарабарщина.

Несмотря на это, я думаю, что должна быть какая-то логика программирования, а не просто одно регулярное выражение.

Ответ 9

Я думаю, что регулярное выражение здесь не помогло бы. Regex будет в основном соответствовать детерминированному вводу, т.е. Регулярное выражение будет иметь предопределенный набор шаблонов, которые он будет соответствовать. И тарабарщина в большинстве случаев была бы случайной. Один из способов - инвертировать проблему, то есть сопоставить соответствующий текст, а не сопоставлять тарабарщину.

Ответ 10

Я бы назвал регулярное выражение "любая пунктуация, за которой следует что-либо, кроме пробела".

Итак, в .NET это возможно что-то вроде

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

Затем вы будете считать "любое слово с двумя или более пунктуациями последовательно:

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

В любом случае, похоже, хороший старт.

Ответ 11

Мне нравится ответ @Breton - я бы предложил использовать его подход "Корпус" также с библиотекой известных "плохих сканирований", что было бы легче идентифицировать, потому что "мусор" имеет большую внутреннюю согласованность, чем "хороший текст", если он приходит от плохих сканирований OCR (например, количество отдельных глифов ниже).

Ответ 12

Еще одна хорошая методика - использовать проверку орфографии/словарь и искать слова "слова" после того, как вы удалили нечитаемый материал с помощью регулярного выражения.