2013-05-12 2 views
-4

Мне нужно разобрать общую сумму из разных файлов. Макет каждого файла отличается, поэтому строки, которые мне нужны для разбора, различаются.Что такое регулярное выражение для захвата общей суммы из строк?

Каким должно быть регулярное выражение для захвата от укуса числа, которое падает после «Всего»?

Он должен быть нечувствительным к регистру и должен учитывать ближайшее соответствие после «Всего». Там может быть что угодно до или после слова «Всего», и мне нужно первое число, которое приходит после него.

Например:

from string "Service charges: 10 Total: 100 Shipping: 10" 
from string "Service charges: 10 Total Amount: 100 Shipping: 10" 
from string "Service charges: 10 Grand Total: 100 Shipping: 10" 
from string "Service charges: 10 Total Amount (Rs.): 100 Shipping: 10" 

Выходной сигнал должен быть во всех указанных выше случаях 100.

+2

Это очень неясно. сделать пример того, что у вас есть и что вы ожидаете – luksch

+0

Почему вы хотите регулярное выражение, когда вы уже используете Nokogiri? – squiguy

+0

@squiguy Как это не правильно отформатированный html, где я могу использовать селектор css или xpath. это было бы проще с текстовым совпадением. – whizcreed

ответ

3

Если все, что вы действительно просят о том, шаблон подходит для различных строк, рассмотрим использование scan и захватить числовые строки:

[ 
    "Service charges: 10 Total: 100 Shipping: 10", 
    "Service charges: 10 Total Amount: 100 Shipping: 10", 
    "Service charges: 10 Grand Total: 100 Shipping: 10", 
    "Service charges: 10 Total Amount (Rs.): 100 Shipping: 10", 
].map{ |s| s.scan(/\d+/)[1] } 
=> ["100", "100", "100", "100"] 

Это предполагает, что вы хотите, второе число в каждой строке.

Если этот заказ будет изменен, это маловероятно, потому что похоже, что вы просматриваете счета-фактуры, тогда изменения в шаблоне и/или scan будут работать.Это переключает его и использует стандартный поиск регулярных выражений, основываясь на местоположении «Total», некоторые возможные вмешиваясь текст, а затем «:» и общее значение:

[ 
    "Service charges: 10 Total: 100 Shipping: 10", 
    "Service charges: 10 Total Amount: 100 Shipping: 10", 
    "Service charges: 10 Grand Total: 100 Shipping: 10", 
    "Service charges: 10 Total Amount (Rs.): 100 Shipping: 10", 
].map{ |s| s[/Total.*?: (\d+)/, 1] } 
=> ["100", "100", "100", "100"] 

Чтобы получить целые значения присоединять to_i внутри map заявления:

[ 
    "Service charges: 10 Total: 100 Shipping: 10", 
    "Service charges: 10 Total Amount: 100 Shipping: 10", 
    "Service charges: 10 Grand Total: 100 Shipping: 10", 
    "Service charges: 10 Total Amount (Rs.): 100 Shipping: 10", 
].map{ |s| s[/Total.*?: (\d+)/, 1].to_i } 
=> [100, 100, 100, 100] 

для примера строк, это, вероятно, предпочтительнее использовать шаблоны с учетом регистра, чтобы соответствовать «Total», если у вас есть знания, которые вы будете сталкиваться «общий» в нижнем регистре. И в этом случае вы должны показать такой пример.

1

Я думаю, что вы можете сделать это:

/Total[^:]*:\s+([0-9]+)/i 

Объяснение:

  • Total Seach для "всего"
  • [^:]* затем ничего или ничего, пока двоеточие ":" является найдено
  • :\s+ читать через двоеточие и любые последующие белые пробелы е (возможно взять * вместо +)
  • ([0-9]+) читать цифры в группу для последующего извлечения -> 100

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

здесь является fiddle as an example

+0

Nokogiri не понимает и не заботится о регулярном выражении. Это касается только разбора XML или HTML и определения узлов с использованием выражений CSS или XPath. –

+0

я вижу. ну, мой ответ о регулярном выражении, а не о синтаксическом анализе html. но я изменяю ответ, чтобы лучше отразить это. – luksch

0
# assuming you have all your files ready in an array 
a = ["Service charges: 10 Total: 100 Shipping: 10", "Service charges: 10 Total Amount: 100 Shipping: 10", "Service charges: 10 Grand Total: 100 Shipping: 10", "Service charges: 10 Total Amount (Rs.): 100 Shipping: 10"] 
# we find every total with the following regexp 
a.map {|s| s[/total[^\d]*(?<total>\d+)/i, 'total']} 
#=> ["100", "100", "100", "100"] 

Регулярное выражение является /total[^\d]*(?<total>\d*)/i. Он ищет слово «total» и игнорирует любой следующий символ, пока не найдет номер (который он возвращает в группе захвата). Опция i делает регистр нечувствительным к регистру.

Смежные вопросы