замените каждое вхождение 'line 2' на line_2 на регулярное выражение - PullRequest
0 голосов
/ 25 августа 2010

Я анализирую некоторый текст из файла XML, в котором есть такие предложения, как «Вычтите строку 4 из строки 1.», «Введите сумму из строки 5» я хочу заменить все вхождения строки на line_ например. Вычтите строку 4 из строки 1 -> Вычтите строку_4 из строки_1

Кроме того, есть предложения типа "Являются ли суммы в строках 4 и 8 одинаковыми?" и «Пропустить строки с 9 по 12; перейти к строке 13». Я хочу обработать эти предложения, чтобы стать "Являются ли суммы на line_4 и line_8 одинаковыми?" а также «Пропустить строки от 9 до 12; перейти к строке 13».

Ответы [ 3 ]

2 голосов
/ 25 августа 2010

Вот рабочая реализация с тестом rspec.Вы называете это так: output = LineIdentifier[input].Для проверки spec file.rb после установки rspec gem.

require 'spec'

class LineIdentifier
  def self.[](input)
    output = input.gsub /line (\d+)/, 'line_\1'
    output.gsub /lines (\d+) (and|from|through) (line )?(\d+)/, 'line_\1 \2 line_\4'
  end
end

describe "LineIdentifier" do
  it "should identify line mentions" do
    examples = { 
      #Input                                         Output
     'Subtract line 4 from line 1.'               => 'Subtract line_4 from line_1.',
     'Enter the amount from line 5'               => 'Enter the amount from line_5',
     'Subtract line 4 from line 1'                => 'Subtract line_4 from line_1',
    }
    examples.each do |input, output|
      LineIdentifier[input].should == output
    end
  end
  it "should identify line ranges" do
    examples = { 
      #Input                                         Output
     'Are the amounts on lines 4 and 8 the same?' => 'Are the amounts on line_4 and line_8 the same?',
     'Skip lines 9 through 12; go to line 13.'    => 'Skip line_9 through line_12; go to line_13.',
    }
    examples.each do |input, output|
      LineIdentifier[input].should == output
    end
  end
end
0 голосов
/ 31 августа 2010

Сед - твой друг:

lines.sed * * 1004

#!/bin/sed -rf
s/lines? ([0-9]+)/line_\1/g
s/\b([0-9]+[a-z]?)\b/line_\1/g

lines.txt

Subtract line 4 from line 1.
Enter the amount from line 5
Are the amounts on lines 4 and 8 the same?
Skip lines 9 through 12; go to line 13.
Enter the total of the amounts from Form 1040A, lines 7, 8a, 9a, 10, 11b, 12b, and 13
Add lines 2, 3, and 4

демо

$ cat lines.txt | ./lines.sed
Subtract line_4 from line_1.
Enter the amount from line_5
Are the amounts on line_4 and line_8 the same?
Skip line_9 through line_12; go to line_13.
Enter the total of the amounts from Form 1040A, line_7, line_8a, line_9a, line_10, line_11b, line_12b, and line_13
Add line_2, line_3, and line_4

Вы также можете превратить это в однострочную строку sed, хотя файл более удобен в обслуживании.

0 голосов
/ 25 августа 2010

Это работает для конкретных примеров, в том числе в комментариях OP.Как это часто бывает при использовании регулярного выражения для анализа, он становится мешаниной с дополнительными случаями и тестами для обработки постоянно растущих известных входных данных.Это обрабатывает списки номеров строк, используя цикл while с не жадным совпадением.Как написано, это просто обрабатывает ввод построчно.Чтобы получить ряд номеров строк через границы строк, его необходимо изменить, чтобы он обрабатывался как один кусок с соответствием между строками.

open( ARGV[0], "r" ) do |file|
  while ( line = file.gets )
    # replace both "line ddd" and "lines ddd" with line_ddd 
    line.gsub!( /(lines?\s)(\d+)/, 'line_\2' )
    # Now replace the known sequences with a non-greedy match
    while line.gsub!( /(line_\d+[a-z]?,?)(\sand\s|\sthrough\s|,\s)(\d+)/, '\1\2line_\3' )
    end
    puts line
  end
end

Пример данных : Для этого ввода:

Subtract line 4 from line 1.
Enter the amount from line 5
on lines 4 and 8 the same?
Skip lines 9 through 12; go to line 13.
... on line 10 Form 1040A, lines 7, 8a, 9a, 10, 11b, 12b, and 13
Add lines 2, 3, and 4

Это выдаёт:

Subtract line_4 from line_1.
Enter the amount from line_5
on line_4 and line_8 the same?
Skip line_9 through line_12; go to line_13.
... on line_10 Form 1040A, line_7, line_8a, line_9a, line_10, line_11b, line_12b, and line_13
Add line_2, line_3, and line_4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...