0

私はエビの宝石を使用して、コンピュータで生成された 60 ページの PDF レポートを読んでいます。このレポートには、数十人の個人の財務データと人口統計データが含まれています。私が直面している課題は、名前/特別な ID (同じ行) と、各行がスキャンされている間にその人に関連する後続の行をキャプチャできるようにしたいということです。文字列に対して ruby​​ のスキャン メソッドを使用すると、次のように一致する行ごとに財務情報だけを取得できました。

[<invoice no.>, <service type>, <modifier (if any)>, <service_date>, <units>, <amount>]

ID を数行下の財務データに関連付けようとしましたが、ID が変更されるたびに変更されましたが、何も機能しませんでした。私はお尻の後ろ向きにこれについて行っていますか?正規表現に関する私の経験はほとんどありません (および一般的なプログラミング)。

以下は、財務データのみで機能するコードです。

PDF::Reader.new(file).pages.each do |page|
  page.raw_content.scan(/^\(\s(\d{6})\s+\d\s+(\w\d{4})\s+(0580|TT|1C|1C\s+1F)?\s+(\d+\/\d+\/\d+)\s+\d+\/\d+\/\d+\s+(\d+\.\d+)\s+(\d+\.\d+)/) do |line|        
    line.collect {|x| x.strip! if !x.nil?}
    print "#{line.join(' ')}\n"
    Cycle.check_details(line)
  end
end

そして、これが生成するもののサンプルですputs page.raw_content(これらの行には空の空白がたくさん含まれています)。

(REG  LOC   CLIENT   SERVICE   NAME                    BIRTH DATE   RECIPIENT ID    PRIOR AUTHORIZATION #)'
(xx   xxx  xxxxx     xxxxxxx    LANNISTER, JAIME         xx/xx/xxxx   xxxx <special ID>)'
(DIAGNOSIS CODES:  887.0)'
( )'
(  INV #   LINE #   PROCEDURE CODE  REVENUE CD   FROM DT   THRU DT     UNITS AMOUNT)'
( <inv num>       1    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       2    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     2.50     41.00)'
( <inv num>       3    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       4    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       5    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       6    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       7    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
(                                                                CLAIM TOTAL
   434.60   CLAIM ACCOUNT REF.  xxxxxxxxxxxxxxxSUP)'

(REG  LOC   CLIENT   SERVICE   NAME                    BIRTH DATE   RECIPIENT ID    PRIOR AUTHORIZATION #)'
(xx   xxx  xxxxx     xxxxxxx    LANNISTER, JOFFREY         xx/xx/xxxx   xxxx <special ID>)'
(DIAGNOSIS CODES:  259.0)'
( )'
(  INV #   LINE #   PROCEDURE CODE  REVENUE CD   FROM DT   THRU DT     UNITS AMOUNT)'
( <inv num>       1    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       2    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     2.50     41.00)'
( <inv num>       3    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       4    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       5    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       6    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       7    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
(                                                                CLAIM TOTAL
   434.60   CLAIM ACCOUNT REF.  xxxxxxxxxxxxxxxSUP)'
4

2 に答える 2

1

すべてが正規表現で解析される候補ではありません。また、データを扱いやすいチャンクに分割した後に正規表現が役立つ場合もあります。あなたのデータは2番目のケースの例です。一部を分解すると、個々の行を簡単に解析できます。

あなたのデータは紛らわしいですが、これはそれを解明します. 先頭(と末尾)'が削除されると、コードは を使用して個々の行に分割しsplit、 を使用slice_beforeして論理的なチャンクに分割します。それらが収集されると、賢明な方法で各ブロックを処理することができます。

require 'prettyprint'

data = "(REG  LOC   CLIENT   SERVICE   NAME                    BIRTH DATE   RECIPIENT ID    PRIOR AUTHORIZATION #)'
(xx   xxx  xxxxx     xxxxxxx    LANNISTER, JAIME         xx/xx/xxxx   xxxx <special ID>)'
(DIAGNOSIS CODES:  887.0)'
( )'
(  INV #   LINE #   PROCEDURE CODE  REVENUE CD   FROM DT   THRU DT     UNITS AMOUNT)'
( <inv num>       1    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       2    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     2.50     41.00)'
( <inv num>       3    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       4    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       5    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       6    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       7    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
(                                                                CLAIM TOTAL
  434.60   CLAIM ACCOUNT REF.  xxxxxxxxxxxxxxxSUP)'

(REG  LOC   CLIENT   SERVICE   NAME                    BIRTH DATE   RECIPIENT ID    PRIOR AUTHORIZATION #)'
(xx   xxx  xxxxx     xxxxxxx    LANNISTER, JOFFREY         xx/xx/xxxx   xxxx <special ID>)'
(DIAGNOSIS CODES:  259.0)'
( )'
(  INV #   LINE #   PROCEDURE CODE  REVENUE CD   FROM DT   THRU DT     UNITS AMOUNT)'
( <inv num>       1    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       2    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     2.50     41.00)'
( <inv num>       3    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       4    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       5    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       6    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
( <inv num>       7    <service_code>  <modifier>                    xx/xx/13  xx/xx/13     4.00     65.60)'
(                                                                CLAIM TOTAL
  434.60   CLAIM ACCOUNT REF.  xxxxxxxxxxxxxxxSUP)'
"

lines = data.gsub(/^\(|\)'$/m, '').split("\n").map{ |s| s.strip }.reject{ |s| s.empty? }.slice_before(/^REG\b/)

この時点で、linesは配列の配列です。各サブアレイは、「REG」で始まる行のブロックで構成されます。slice_before新しい行が一致するたび/^REG\b/に、新しいサブアレイ/ブロックが作成されます。linesハッシュから配列または単一のキーと値のペアを取得する前の準備オブジェクトのような列挙子です。列挙子を反復処理できます。これが私たちがやりたいことです。

patient_data = lines.map { |sub_ary|
  sub_ary[1][/(?:\S+ \s+ ){4} (\S+, \s+ \S+) \s+ (?:\S+ \s+){2} (.+)$/x]
  patient_name, special_id = $1, $2

  invoice_info = sub_ary[5..-3].map{ |line|
    line[/^(\S+) \s+ \S+ \s+ (\S+) \s+ (\S+)/x]
    [$1, $2, $3]
  }

  {
    patient_name: patient_name,
    special_id:   special_id,
    invoice_info: invoice_info
  }
}

pp patient_data

どの出力:

[{:patient_name=>"LANNISTER, JAIME",
  :special_id=>"<special ID>",
  :invoice_info=>
  [["<inv_num>", "<service_code>", "<modifier>"],
    ["<inv_num>", "<service_code>", "<modifier>"],
    ["<inv_num>", "<service_code>", "<modifier>"],
    ["<inv_num>", "<service_code>", "<modifier>"],
    ["<inv_num>", "<service_code>", "<modifier>"],
    ["<inv_num>", "<service_code>", "<modifier>"]]},
{:patient_name=>"LANNISTER, JOFFREY",
  :special_id=>"<special ID>",
  :invoice_info=>
  [["<inv_num>", "<service_code>", "<modifier>"],
    ["<inv_num>", "<service_code>", "<modifier>"],
    ["<inv_num>", "<service_code>", "<modifier>"],
    ["<inv_num>", "<service_code>", "<modifier>"],
    ["<inv_num>", "<service_code>", "<modifier>"],
    ["<inv_num>", "<service_code>", "<modifier>"]]}]

これはあなたを近づけますが、問題を完全には解決しません。レコードから必要なすべてのフィールドを取得するようにコードを変更する方法を理解することは、意図的にあなたに任せています。

于 2013-08-05T21:18:37.470 に答える
0

正規表現をテストしたい場合は、http://rubular.com/ をチェックしてください

これは非常に便利なツールであり、正規表現の基本のほとんどがページの下部にあります

于 2013-08-05T19:50:15.253 に答える