medattrib 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,185 @@
1
+ =begin
2
+ Copyright 2015 The MITRE Corporation
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ class RouteTagger < ListTagger
18
+ def initialize
19
+ @name = 'route'
20
+ @list = [/ORAL(?:ly)?/i,
21
+ /p\.o\./i,
22
+ /po\b/i,
23
+ /by\s+mouth/i,
24
+ /per\s+(?:oris|rectum|nostril|mouth)/i,
25
+ /INTRAVENOUS(?:ly)?/i,
26
+ /SUBCU(?:TANEOUS(?:ly)?)?/i,
27
+ /subq\.?/i,
28
+ /INTRAPERITONEAL(?:ly)?/i,
29
+ /INTRAMUSCULAR(?:ly)?/i,
30
+ /INTRATHORACIC/i,
31
+ /INTRA-ARTICULAR(?:ly)?/i,
32
+ /INTRADERMAL(?:ly)?/i,
33
+ /EPIDURAL(?:ly)?/i,
34
+ /INTRASINAL(?:ly)?/i,
35
+ /TOPICAL(?:ly)?/i,
36
+ /AURICULAR(?:ly)?/i,
37
+ /OTIC/i,
38
+ /((?:right|left|both)\s+)?ears?/i,
39
+ /NASAL(?:ly)?/i,
40
+ /nose/i,
41
+ /opthalimic/i,
42
+ /eyes?/i,
43
+ /VAGINAL(?:ly)?/i,
44
+ /RECTAL (?:ly)?/i,
45
+ /URETHRAL(?:ly)?/i,
46
+ /INHALATION/i,
47
+ /INTRASYNOVIAL(?:ly)?/i,
48
+ /INTRATUMOR/i,
49
+ /INTRAVASCULAR(?:ly)?/i,
50
+ /INTRASPINAL(?:ly)?/i,
51
+ /INTRACAVITARY/i,
52
+ /SUBLINGUAL(?:ly)?/i,
53
+ /INTRABURSAL/i,
54
+ /INTRACARDIAC/i,
55
+ /INTRAUTERINE/i,
56
+ /CAUDAL BLOCK/i,
57
+ /BUCCAL(?:ly)?/i,
58
+ /CNBLK/i,
59
+ /INTRATHECAL(?:ly)?/i,
60
+ /RETROBULBAR/i,
61
+ /INTRATRACHEAL(?:ly)?/i,
62
+ /INTRAOCULAR(?:ly)?/i,
63
+ /INTRA-ARTERIAL(?:ly)?/i,
64
+ /DENTAL(?:ly)?/i,
65
+ /PERIODONTAL(?:ly)?/i,
66
+ /IMPLANTATION/i,
67
+ /INTRALESIONAL/i,
68
+ /INTRAPLEURAL/i,
69
+ /PERIARTICULAR/i,
70
+ /INTRAGASTRIC/i,
71
+ /INTRADUODENAL/i,
72
+ /INTRAVENTRICULAR/i,
73
+ /INTRATENDINOUS/i,
74
+ /PERIDURAL/i,
75
+ /INTRACERVICAL/i,
76
+ /INTRADURAL/i,
77
+ /SUBMUCOSAL/i,
78
+ /VOCAL CORDS/i,
79
+ /INTRA-ABDOMINAL/i,
80
+ /EXTRACORPOREAL/i,
81
+ /NERVE BLOCK/i,
82
+ /INTRA-AMNIOTIC/i,
83
+ /INTRAPROSTATIC/i,
84
+ /INVITRO/i,
85
+ /SUBARACHNOID/i,
86
+ /INTRABRONCHIAL/i,
87
+ /CONJUNCTIVAL/i,
88
+ /NASOGASTRIC/i,
89
+ /INTRAESOPHAGEAL/i,
90
+ /INTERSTITIAL/i,
91
+ /IV\b/i,
92
+ /IM\b/i,
93
+ /SUBCONJUNCTIVAL/i,
94
+ /SURGICAL/i,
95
+ /AN,INFILTRATION/i,
96
+ /AN,SURFACE/i,
97
+ /INTRATHECAL/i,
98
+ /ORAL-21/i,
99
+ /ORAL-28/i,
100
+ /ORAL-20/i,
101
+ /BUCCAL\/SUBLINGUAL/i,
102
+ /SOFT TISSUE/i,
103
+ /INTRATESTICULAR/i,
104
+ /URETERAL/i,
105
+ /PERCUTANEOUS/i,
106
+ /S(?:C|Q)\b/i,
107
+ /INFUSION/i,
108
+ /INHALATION, NASAL/i,
109
+ /PERFUSION/i,
110
+ /INTRACORONAL, DENTAL/i,
111
+ /PERFUSION\/CARDIAC/i,
112
+ /INTRACORONARY/i,
113
+ /ENDOCAVITARY/i,
114
+ /INTRADISCAL/i,
115
+ /(?:TRANS)?MUCOSAL/i,
116
+ /mucous membrane/i,
117
+ /INTRADUCTAL/i,
118
+ /TRANSTYMPANIC/i,
119
+ /PERFUSION, BILIARY/i,
120
+ /INTRAEPIDERMAL/i,
121
+ /INTRAGINGIVAL/i,
122
+ /INTRALUMINAL/i,
123
+ /INTRAVITREAL/i,
124
+ /ENTERAL/i,
125
+ /INTRAPERICARDIAL/i,
126
+ /INTRALYMPHATIC/i,
127
+ /INTRATUBULAR/i,
128
+ /INTRAOVARIAN/i,
129
+ /TRANSTRACHEAL/i,
130
+ /SPINAL/i,
131
+ /ELECTRO-OSMOSIS/i,
132
+ /(?:TRANS)?DERMAL/i,
133
+ /PHOTOPHERESIS/i,
134
+ /THROAT/i,
135
+ /INFILTRATION/i,
136
+ /INTRABILIARY/i,
137
+ /INTRACARTILAGINOUS/i,
138
+ /UNASSIGNED/i,
139
+ /LARYNGEAL/i,
140
+ /INTRAILEAL/i,
141
+ /IRRIGATION/i,
142
+ /IONTOPHORESIS/i,
143
+ /AN,SYMPATHETIC NBLK/i,
144
+ /INTRAVESICAL/i,
145
+ /INTRAVESICAL/i,
146
+ /INTRATYMPANIC/i,
147
+ /ENDOTRACHEAL/i,
148
+ /EXTRA-AMNIOTIC/i,
149
+ /INTRACORPORUS CAVERNOSUM/i,
150
+ /INTRACEREBRAL/i,
151
+ /INTRACISTERNAL/i,
152
+ /INTRACORNEAL/i,
153
+ /INTRAMEDULLARY/i,
154
+ /INTRAMENINGEAL/i,
155
+ /OROPHARYNGEAL/i,
156
+ /PARENTERAL/i,
157
+ /PERINEURAL/i,
158
+ /INTRACAUDAL/i,
159
+ /INTRAPULMONARY/i,
160
+ /AURICULAR/i,
161
+ /(?:SUB-)?CUTANEOUS/i,
162
+ /ENDOCERVICAL/i,
163
+ /INTRACAVERNOUS/i,
164
+ /ENDOSINUSIAL/i,
165
+ /OCCLUSIVE DRESSING TECHNIQUE/i,
166
+ /RESPIRATORY/i,
167
+ /INTRAVENOUS DRIP/i,
168
+ /INTRAVENOUS BOLUS/i,
169
+ /HEMODIALYSIS/i,
170
+ /TRANSPLACENTAL/i,
171
+ /INTRAEPICARDIAL/i,
172
+ /INTRAHEPATIC/i,
173
+ /INTRALINGUAL/i,
174
+ /INTRAMAMMARY/i,
175
+ /INTRANODAL/i,
176
+ /INTRAOMENTUM/i,
177
+ /INTRARUMINAL/i,
178
+ /SUBGINGIVAL/i,
179
+ /SUBRETINAL/i,
180
+ /TRANSENDOCARDIAL/i,
181
+ /OPHTHALMIC/i,
182
+ /\b(?:OD|OS)\b/i,
183
+ /apply\s+to\s+(?:skin|affected\s+areas?)/i]
184
+ end
185
+ end
data/lib/medattrib.rb ADDED
@@ -0,0 +1,80 @@
1
+ =begin
2
+ Copyright 2015 The MITRE Corporation
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+
16
+
17
+ A replacement for MedAttrib.pl.
18
+
19
+ The MedAttrib class method parse(text) returns an
20
+ AnnotatedString which contains the original text and a list of the tags
21
+ found. Because "doseamount" depends on the presence of other tags,
22
+ the taggers have been split into pre- and post-doseamount taggers.
23
+
24
+ Example usage:
25
+ tagger = MedAttrib.new
26
+ annotated_string = tagger.parse("take daily.")
27
+ # annotated_string is now "take daily." with a "freq" tag labeling "daily" in standoff annotation (class AnnotatedString). This can be printed as inline xml using AnnotatedString#to_s:
28
+
29
+ puts annotated_string
30
+ #=> "take <freq>daily</freq>."
31
+ =end
32
+
33
+ gem 'standoff', '>=0.0.3' #data model
34
+ require 'standoff'
35
+
36
+ require_relative 'tagger.rb' #taggers based on regex contexts
37
+ require_relative 'list_tagger.rb' #taggers based on term lists
38
+
39
+ #Tagger child classes:
40
+ require_relative 'taggers/dose_amount_tagger.rb'
41
+ require_relative 'taggers/strength_tagger.rb'
42
+ require_relative 'taggers/strength_unit_tagger.rb'
43
+ require_relative 'taggers/indication_tagger.rb'
44
+ require_relative 'taggers/duration_tagger.rb'
45
+ require_relative 'taggers/dispense_quantity_tagger.rb'
46
+ require_relative 'taggers/refill_tagger.rb'
47
+ require_relative 'taggers/substitution_tagger.rb'
48
+ require_relative 'taggers/timing_tagger.rb'
49
+
50
+ #ListTagger child classes:
51
+ require_relative 'list_taggers/dose_form_tagger.rb'
52
+ require_relative 'list_taggers/route_tagger.rb'
53
+ require_relative 'list_taggers/frequency_tagger.rb'
54
+
55
+
56
+ class MedAttrib
57
+ def parse (text)
58
+ text = REXML::Text.new(text, false, nil, false).to_s # escape special characters
59
+ taggersExceptDoseAmount = [StrengthTagger.new,
60
+ StrengthUnitTagger.new,
61
+ DoseFormTagger.new,
62
+ RouteTagger.new,
63
+ IndicationTagger.new,
64
+ FrequencyTagger.new,
65
+ TimingTagger.new,
66
+ SubstitutionTagger.new,
67
+ RefillTagger.new,
68
+ DurationTagger.new,
69
+ DispenseQuantityTagger.new]
70
+
71
+ tags = []
72
+ taggersExceptDoseAmount.each {|tagger| tags += tagger.parse_main text}
73
+ as = Standoff::AnnotatedString.new(:signal => text, :tags => tags)
74
+ DoseAmountTagger.new.parse_annotated_string as
75
+ partial_xml = as.to_s
76
+ as
77
+
78
+ end
79
+
80
+ end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ =begin
4
+ Copyright 2015 The MITRE Corporation
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ require './medattrib.rb'
20
+
21
+ while line = gets do
22
+ puts runall(line).to_s
23
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require "medattrib"
4
+
5
+ tagger = MedAttrib.new
6
+
7
+ while line = gets do
8
+ puts tagger.parse(line).to_s
9
+ end
data/lib/tagger.rb ADDED
@@ -0,0 +1,91 @@
1
+ =begin
2
+ Copyright 2015 The MITRE Corporation
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ class Tagger
18
+
19
+ @@unit_search_global =
20
+ /(?:units?|micrograms?|milligrams?|mg|grams?|millimoles?
21
+ |milliequivalents?|percent|(?:au|pnu)(?:\/|per\s*)ml
22
+ |mg\.?(?:(?:\/|per\s*)(one|five|1|5)?\s*(?:ml|cc)\.?)?
23
+ |\%|gr\.?|meq\.?|mmol\.?|ugm?s?|mcg)/i
24
+
25
+ @@number_word_search =
26
+ /(?:one|two|three|four|five|six|seven|eight|nine|ten|fifteen|twenty|thirty|sixty)/
27
+
28
+ @@number_numeric_search =
29
+ /(?:\d+\/)?\d+(?:\.\d+)?/
30
+
31
+ @@number_numeric_or_word_search =
32
+ /(?:(?:#{@@number_numeric_search})|(?:#{@@number_word_search}))/
33
+
34
+ @@number_hundred_thousand_search =
35
+ /(?:\shundred|\sthousand)/
36
+
37
+ # search for number (word or numeric) with optional hundred or thousand modifier
38
+ @@number_complete_search =
39
+ /(?:#{@@number_numeric_or_word_search})(?:\s(?:#{@@number_hundred_thousand_search}))?/
40
+
41
+ @content_group = 1
42
+
43
+ # @@numberSearch =
44
+ # /(?:#{@@number_numeric_or_word_search})
45
+ # (?:\shundred|\sthousand)?(?:(?:-|\s+to\s+)
46
+ # (?:\d+(?:\.\d+)?|one|two)
47
+ # (?:\shundred|\sthousand)?)?/i
48
+
49
+ def parse_text(text, precondition, search, content_group = @content_group)
50
+ tags = []
51
+ if text =~ precondition
52
+
53
+ #if there are multiple instances, this will find them all
54
+ #and record them as separate tags, as well as preserving their
55
+ #location in the text
56
+ window = text.dup
57
+ textlocation = 0
58
+ while window =~ search
59
+ instance = search.match window
60
+ beginning = textlocation + instance.begin(content_group)
61
+ ending = textlocation + instance.end(content_group)
62
+ textlocation = ending
63
+ content = instance[content_group]
64
+ window = window.slice instance.end(content_group)..window.length
65
+ normalized = normalize content
66
+ attributes = normalized ? {:normalized => normalized} : {}
67
+ tags << Standoff::Tag.new(:content => content,
68
+ :attributes => attributes,
69
+ :name => @name,
70
+ :start => beginning,
71
+ :end => ending)
72
+ end
73
+ end
74
+
75
+ return tags
76
+ end
77
+
78
+ @default_precondition = //
79
+ @default_search = //
80
+ @content_group = 1
81
+
82
+ def parse_main(text)
83
+ tags = parse_text(text, @default_precondition, @default_search, @content_group)
84
+ end
85
+
86
+ def normalize(text)
87
+ # placeholder for Tagger-subclass-specific normalization mappers,
88
+ # e.g. "once a day" => :qd for the FrequencyTagger
89
+ end
90
+
91
+ end
@@ -0,0 +1,37 @@
1
+ =begin
2
+ Copyright 2015 The MITRE Corporation
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ class DispenseQuantityTagger < Tagger
18
+ def initialize
19
+ @default_precondition = /(?:dispense|quantity)\s+(?:$be\s+)?\d+/i
20
+ @default_search = /((?:(?:dispense|quantity)\s+)(?:$be\s+)?)(\d+)/i
21
+ @content_group = 2
22
+ @name = 'dispense'
23
+ end
24
+
25
+ def parse_text(text, precondition, search, content_group)
26
+ tags = super text, @default_precondition, @default_search
27
+ local_precondition = /(?x)(?:dispense|quantity)\s+(?:$be\s+)?(?:one|two|three|
28
+ four|five|six|seven|eight|nine|ten|eleven|twelve|fifteen|
29
+ twenty|thirty|forty|fifty|sixty)/i
30
+ local_search = /(?x)((?:dispense|quantity)\s+(?:$be\s+)?)(one|two|
31
+ three|four|five|six|seven|eight|nine|ten|eleven|
32
+ twelve|thirty|forty|fifty|sixty)/i
33
+ tags += super text, local_precondition, local_search
34
+ return tags
35
+ end
36
+ end
37
+
@@ -0,0 +1,68 @@
1
+ =begin
2
+ Copyright 2015 The MITRE Corporation
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ class DoseAmountTagger < Tagger
18
+ # TODO replace the use of regular expressions searching for "<doseform" with checking for presence of the standoff annotations
19
+ def initialize
20
+ @name = 'doseamount'
21
+ @content_group = 1
22
+
23
+ @shared_search = /(?x)(?:puffs?|tablespoons?|teaspoons?|bolus(?:es)?|
24
+ scoops?|caps?fuls?|ampules?|tubes?|drops?|gtts?|
25
+ milliliters?|ml|c\.c\.|cc\b|\bL\b|tsp|tbsp)/i
26
+ @default_precondition = /(<doseform)/i
27
+ @default_search = /(?x)((?:\d\s+)?(?:\d(?:\/|-))?\d+(?:\.\d+)?
28
+ (?:\s?(?:-|\/)\s+\d+)?|one|two)(\s+<strength>
29
+ (?:[^<])+<\/strength>\s+<strength_unit>(?:[^<])+
30
+ <\/strength_unit>)?(\s+<doseform)/i
31
+
32
+ end
33
+
34
+ def parse_annotated_string(as)
35
+ new_tags = parse_text as.to_s, @default_precondition, @default_search
36
+ local_precondition = /((#{@shared_search})|<route)/i
37
+ local_search = /(?x)((?:(?:\d\s+)?(?:\d(?:\/|-))?(?:\d+(?:\.\d+)?
38
+ (?:\s?(?:-|\/)\s?\d+)?)|one|two))(\s+
39
+ (?:(?:#{@shared_search})|<route))/i
40
+
41
+ new_tags += parse_text as.to_s, local_precondition, local_search
42
+ as.tags += new_tags
43
+ return as
44
+ end
45
+
46
+ def normalize(dose)
47
+ re = {:int => /^\d+$/,
48
+ :decimal => /^(\d+)?\.\d+$/,
49
+ :fraction => /^(\d+) ?\/ ?(\d+)$/,
50
+ :compound => /^(\d+) (\d+) ?\/ ?(\d+)$/,
51
+ :range => /^([0-9\/\.]+) ?- ?([0-9\/\.]+)$/}
52
+ x = case dose
53
+ when re[:int]
54
+ Integer dose
55
+ when re[:decimal]
56
+ Float dose
57
+ when re[:fraction] # simple fraction
58
+ num, denom = dose.split '/'
59
+ Float(num) / Float(denom)
60
+ when re[:compound] # compound fraction
61
+ Integer(dose[re[:compound], 1]) + Float(dose[re[:compound], 2] )/Float(dose[re[:compound], 3])
62
+ when re[:range]
63
+ normalize(dose[re[:range], 1]) .. normalize(dose[re[:range], 2])
64
+ else
65
+ [nil,"one","two","three","four","five","six","seven","eight","nine","ten"].index dose.downcase
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,28 @@
1
+ =begin
2
+ Copyright 2015 The MITRE Corporation
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ class DurationTagger < Tagger
18
+ def initialize
19
+ @shared_search = /(?x)(?:\d+(?:\-\d)?|one|two|three|four|five|six|seven|
20
+ eight|nine|ten|fifteen|twenty|thirty|sixty)\s*
21
+ (?:days?|weeks?|wks|months?|d\b)/i
22
+ @default_precondition = /#{@shared_search}/i
23
+ @default_search = /(?x)((?:for|x)\s?(?:a\stotal\sof\s+)?(?:up\s+to\s+)?
24
+ (?:the\snext\s+)?)(#{@shared_search})/i
25
+ @content_group = 2
26
+ @name = 'duration'
27
+ end
28
+ end
@@ -0,0 +1,30 @@
1
+ =begin
2
+ Copyright 2015 The MITRE Corporation
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ class IndicationTagger < Tagger
18
+ def initialize
19
+ @shared_search = /(?x)(?:(?:(?:severe|high|hyper|hypo|low)\s*)?
20
+ (?:(?:chest\s+)?pain|cholesterol(?:emia)
21
+ |constipation|allergic\s+rhinitis|allergy|anxiety|bone\s+
22
+ loss|indigestion|headache|nausea|osteoporosis|wheez
23
+ (?:e|ing)|edema|discomfort|itch(?:ing)?|c\.?\s*diff))/i
24
+ @default_precondition = /#{@shared_search}/i
25
+ @default_search = /(?x)((?:p\.?r\.?n\.?|(?:as\s+needed\s+)?
26
+ for|prevention\s+of)\s+)(#{@shared_search})/i
27
+ @content_group = 2
28
+ @name = 'indication'
29
+ end
30
+ end
@@ -0,0 +1,58 @@
1
+ =begin
2
+ Copyright 2015 The MITRE Corporation
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ class RefillTagger < Tagger
18
+ def initialize
19
+ @default_precondition = /\d+\s+refills?/i
20
+ @default_search = /(\d+)(\s+refills?)/i
21
+ @content_group = 1
22
+ @name = 'refill'
23
+ end
24
+ def parse_text(text, precondition, search, content_group)
25
+ tags = super text, @default_precondition, @default_search, @content_group
26
+
27
+ local_precondition = /refill\s+\d+\s+times?/i
28
+ local_search = /(refill\s+)(\d+)(\s+times?)/i
29
+ local_content_group = 2
30
+ tags += super text, local_precondition, local_search, local_content_group
31
+
32
+ @precondition = /refills?\s+times\s+\d+/i
33
+ @search = /(refills?\s+times\s+)(\d+)/i
34
+ tags += super text, local_precondition, local_search, local_content_group
35
+
36
+ local_precondition = /(?x)\b(?:no|zero|one|two|three|four|five|six|seven|
37
+ eight|nine|ten|eleven|twelve)\s+refills?/i
38
+ local_search = /(?x)\b(no|zero|one|two|three|four|five|six|seven|
39
+ eight|nine|ten|eleven|twelve)(\s+refills?)/i
40
+ local_content_group = 1
41
+ tags += super text, local_precondition, local_search, local_content_group
42
+
43
+ @precondition = /(?x)refill\s+(?:no|zero|one|two|three|four|five|six|
44
+ seven|eight|nine|ten|eleven|twelve)\s+times?/i
45
+ @search = /(?x)(refill\s+)(no|zero|one|two|three|four|five|six|
46
+ seven|eight|nine|ten|eleven|twelve)(\s+times?)/i
47
+ local_content_group = 2
48
+ tags += super text, local_precondition, local_search, local_content_group
49
+
50
+ @precondition = /(?x)(?:refills?\s+(?:times\s+)?)(?:none|zero|one|two|
51
+ three|four|five|six|seven|eight|nine|ten|eleven|twelve)+/i
52
+ @search = /(?x)(refills?\s+(?:times\s+)?)(none|zero|one|two|
53
+ three|four|five|six|seven|eight|nine|ten|eleven|twelve)/i
54
+
55
+ tags += super text, local_precondition, local_search, local_content_group
56
+ return tags
57
+ end
58
+ end
@@ -0,0 +1,38 @@
1
+ =begin
2
+ Copyright 2015 The MITRE Corporation
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ class StrengthTagger < Tagger
18
+ def initialize
19
+ @shared_search = /(?x)(?:units?|micrograms?|milligrams?|grams?|millimoles?
20
+ |milliequivalents?|percent|(?:au|pnu)(?:\/|per\s*)ml
21
+ |mg\.?(?:(?:\/|per\s*)(one|five|1|5)?\s*(?:ml|cc)\.?)?
22
+ |\%|gr\.?|meq\.?|mmol\.?|ugm?s?|mcg)/i
23
+ @default_precondition = /\s(\.\d+)\s+#{@shared_search}/i
24
+ @default_search = /\s(\.\d+)\s*(#{@shared_search})/i
25
+ @content_group = 1
26
+ @name = 'strength'
27
+ end
28
+ def parse_text(text, precondition, search, content_group)
29
+ tags = super text, @default_precondition, @default_search
30
+ local_precondition = /#{@shared_search}/i
31
+ local_search = /(?x)\s((?:(?:\d+\/)?\d+(?:\.\d+)?|one|two)
32
+ (?:\shundred|\sthousand)?(?:(?:-|\s+to\s+)
33
+ (?:\d+(?:\.\d+)?|one|two)
34
+ (?:\shundred|\sthousand)?)?)\s*(#{@shared_search})/i
35
+ tags += super text, local_precondition, local_search
36
+ return tags
37
+ end
38
+ end