Изменить скрипт Perl для вывода новой строки каждые 20 слов - PullRequest
1 голос
/ 28 ноября 2011

Я использую Perl-скрипт с открытым исходным кодом для создания текстового корпуса на основе англоязычного дампа Википедии. Простой текст был извлечен, но все еще необходимо удалить различные знаки препинания и тому подобное. Однако выходные данные этого сценария по существу создают текстовый файл 7,2 ГБ, содержащий одну строку. Из-за моих потребностей я хочу изменить скрипт так, чтобы он вставлял символ новой строки каждые 20 слов.

Пока я пробовал это:

$wordCount=0;

while (<STDIN>) {
  $wordCount++;

  //text processing regex commands here


  # Remove ellipses 
  s/\.\.\./ /g;

  # Remove dashes surrounded by spaces (e.g. phrase - phrase)
  s/\s-+\s/ /g;

  # Remove dashes between words with no spaces (e.g. word--word)
  s/([A-Za-z0-9])\-\-([A-Za-z0-9])/$1 $2/g;

  # Remove dash at a word end (e.g. three- to five-year)
  s/(\w)-\s/$1 /g;

  # Remove some punctuation
  s/([\"\�,;:%�?�!()\[\]{}<>_\.])/ /g;

  # Remove trailing space
  s/ $//;

  # Remove double single-quotes 
  s/'' / /g;
  s/ ''/ /g;

  # Replace accented e with normal e for consistency with the CMU pronunciation dictionary
  s/�/e/g;

  # Remove single quotes used as quotation marks (e.g. some 'phrase in quotes')
  s/\s'([\w\s]+[\w])'\s/ $1 /g;

  # Remove double spaces
  s/  / /g;


  chomp($_);

  if ($wordCount == 20){
    print uc($_) . "\n";
    $wordCount=0;
  }

  print uc($_) . " ";
}

print "\n";

Однако, похоже, это не сработает, поскольку необработанный вывод содержит только новые строки, произвольно разбросанные вокруг. Я хотел бы отформатировать текст, чтобы он помещался на обычном мониторе шириной 1200 пикселей без переноса слов.

Пример ввода текста из файла

Краткий Оксфордский Словарь Политики. Сторонники анархизма (известные как "анархисты") защищают общества без гражданства как единственную моральную форма социальной организации. Есть много типов и традиций анархизм, не все из которых являются взаимоисключающими. Анархизм как Общественное движение регулярно терпело колебания популярности. Термин анархизм происходит от греческого ἄναρχος, анархос, что означает «без правителей», его использование в качестве синонима все еще распространено за пределами Соединенные Штаты. Самые ранние анархистские темы можно найти в 6-м до н.э. среди произведений даосского философа Лаоцзы, а в более поздних веками Чжуанцзы и Бао Цзинъяня. Термин «анархист» первый вошел в английский язык в 1642 году, во время гражданской войны в Англии, а термин злоупотребления, используемый роялистами против своих противников. Ко времени Французской революции некоторые, такие как Enragés, начали использовать термин позитивно, в отличие от якобинской централизации власти, рассматривая "революционное правительство" как оксюморонное. Посредством На рубеже 19-го века английское слово «анархизм» утратило свою первоначальный негативный оттенок. Современный анархизм возник из светского или религиозная мысль о Просвещении, особенно Жан-Жак Аргументы Руссо о моральной важности свободы. Анархизм", Encarta Online Encyclopedia 2006 (версия для Великобритании). Из этого климата Уильям Годвин разработал то, что многие считают первым выражением современная анархистская мысль. Годвин был, по словам Петра Кропоткина, «первым сформулировать политические и экономические концепции анархизм, хотя он не дал это имя идее разработал в своей работе ", в то время как Годвин приложил свои анархистские идеи к ранний Эдмунд Берк. Анархо-коммунист Джозеф Дежак был первый человек, который назвал себя «либертарианцем». В отличие от Прудона, он утверждал, что "это не продукт его или ее труда, что работник имеет право, но на удовлетворение своих потребностей, какой бы ни была их природа. Иисус иногда считается первым анархист в христианской анархистской традиции. Жорж Лечартье писал, что «Истинным основателем анархии был Иисус Христос и В Европе жесткая реакция последовала за революциями 1848 года, во время которых десять стран испытали краткие или долгосрочные социальные потрясения, как группы проводили националистические восстания. После большинства из них попытки систематических изменений закончились неудачей, консервативные элементы воспользовались разделенными группами социалистов, анархистов, либералы и националисты, чтобы предотвратить дальнейшее восстание. бланкисты, Филадельфии, английские профсоюзные деятели, социалисты и социальные демократы. Благодаря своим связям с активными рабочими движениями, Международная стала важной организацией. Карл Маркс стал ведущая фигура в Интернационале и член ее общего Совет. Последователи Прудона, мутуалисты, выступили против государства Маркса социализм, выступающий за политический абсентизм и мелкую собственность холдинги. В 1868 году, после их неудачного участия в Лига мира и свободы (ФНЧ), русский революционер Михаил Бакунини его коллективистская анархистская ассоциация присоединилась к Первому Интернационалу (который решил не связываться с ФНБ).Сначала коллективисты работали с марксистами, чтобы подтолкнуть Первый Интернационал в более революционное социалистическое русло.Впоследствии Интернационал стал поляризованным на два лагеря с Марксом и Бакуниным в качестве их соответствующих подставных лиц.В 1872 году конфликт завершился окончательным расколом между двумя группами на Гаагском конгрессе, где Бакунин и Джеймс Гийом были исключены из Интернационала, а его штаб-квартира была переведена в Нью-Йорк.В ответ федеральные секции сформировали свой собственный Интернационал на Конгрессе Сент-Имье, приняв революционную анархистскую программу.Black Rose Books 2005) ISBN 1-55164-251-4.

В файле есть текст на 7 с лишним гигабайт.Поэтому использование списка или другой структуры данных может быть немного излишним для этих требований.

Что необходимо для того, чтобы соответствовать моим требованиям?

Ответы [ 5 ]

6 голосов
/ 28 ноября 2011

Попробуйте использовать что-то вроде Text :: Wrap или Text :: Autoformat .

1 голос
/ 28 ноября 2011
open my $in, '<', $inFileName; 
open my $out, '>', $outFileName; 
my $wordcount = 0; 

while(defined( my $line = <$in> )){ 
  $line=~s/\n//g; #remove newline character
  #split the words into an array(could use '\W+' instead of ' ')
  my @words = split ' ', $line; 

  foreach my $word (@words){ 
    $wordCount++; 
    if ($wordCount == 20){ 
      $wordCount = 0; 
      print $out "\n"; 
    }
    else {
      print $out uc($word)." ";
    }
  } # end of foreach line in input 
} # end of file while loop 
close $in; 
close $out; 
0 голосов
/ 29 ноября 2011

Сначала установите разделитель входных записей в Perl на что-то частое и полезное, например, пробел:

$/ = ' ';

, затем зациклите ввод word на word :

while (<>) {

обрезать слово :

    s/^\s+|\s+$//g;

пропустить его, если было все пространство:

    $_ or next;

сделать любые другие преобразования васнужно

, а затем добавить его в стек, разбив любые внутренние вкладки или другие символы, похожие на пробелы:

    push @words, split /\s+/; 

далее, проверьте, есть ли у вас 20 слов, и если да,напечатайте их:

    print join(' ' => splice @words, 0, 20), "\n" while @words >= 20;
}

, затем напечатайте все, что осталось:

print "@words\n" if @words;
0 голосов
/ 29 ноября 2011

Верно для Perl, есть разные способы решения этой проблемы, но один (извращенный ?!) способ сделать это - прочитать файл побайтово, а не построчно, или вылить все это целиком. Это довольно грубо форс, но это работает. По сути, вы торгуете использованием памяти для использования диска.

#!/usr/bin/perl -w
use strict;

open(IN, "in.txt") or die;
my $rc = 1;
my $wc = 0;
my $new;
while ($rc != 0)
{
  # Read a byte - not safe for Unicode or other double-byte environments!
  $rc = read IN, $new, 1, 0;

  # We're only interested if the byte isn't punctuation (POSIX character class).
  if ($new !~ m/[[:punct:]]/)
  {
    # word boundary?
    if ($new =~ m/ /)
    {
      $wc++;
      if ($wc % 20 == 0)
      {
        print "\n";  # 20th word, time for a new line.
      }
    }
    print $new;
  }

  # move on to the next byte
  seek IN, 0, 1;
}

close(IN);
0 голосов
/ 28 ноября 2011

Не зная более подробной информации об этой проблеме, я бы предложил решение грубой силы: отбросить всю запись, разбить на массив на основе "", создать массив и выводить "\ n" после каждых 20 элементов.*

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...