oddb2xml 2.0.9 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/Gemfile.lock +1 -1
- data/History.txt +4 -0
- data/dokumentation_calc.textile +139 -21
- data/lib/oddb2xml/builder.rb +1 -1
- data/lib/oddb2xml/calc.rb +55 -56
- data/lib/oddb2xml/compositions_syntax.rb +101 -3
- data/lib/oddb2xml/parslet_compositions.rb +44 -0
- data/lib/oddb2xml/version.rb +1 -1
- data/spec/calc_spec.rb +28 -30
- data/spec/data/swissmedic_package-galenic.xlsx +0 -0
- data/spec/galenic_spec.rb +324 -0
- data/spec/spec_helper.rb +1 -0
- metadata +38 -36
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MWIzODZlNjVlYTgzMzIxNDUwNmQ1NjgwMjdhNGFkNWEwNmI2NjExYQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NDYwYWMxMmQ5YjVlNWM4NmNlOTU4NWY0NDU2YjRhZThlNTUzNjhmNw==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NzQ1OWJlMmVlZDMzM2ZkMDM0M2Q0MzNlNGEyNzYxNGE0YjYxN2FjM2RkNjM0
|
10
|
+
Y2Y0Yjk4YTkxZGY5YTBjODMzYWE2ZjQ3NGZlMzU5YTUxZmI0N2QxZGY5MDQ0
|
11
|
+
YjRjMWIyNWNmZGI1YzYyOTBiODU2MjU1MDFkODU5MjIyOTczYjE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MjIxZWJkY2JmNzhlOGNhNTljMDUwZmU3YThhODAwYTNiNTYxMTg0MDE3ZDcy
|
14
|
+
MGMzNjA0MGY4ODFlZWJjM2MzYzIxOTU4MTVkOWVhMTUxMzBhOTE4MDQ5OTM3
|
15
|
+
ODY4ZDY0ZWNjZDQ1YzY2NTQ0ZDQyNDI1MjgxYmYwNDkyNzcyMTY=
|
data/Gemfile.lock
CHANGED
data/History.txt
CHANGED
data/dokumentation_calc.textile
CHANGED
@@ -23,34 +23,152 @@ Die Syntax wird in einer Datei "compositions_syntax":https://raw.githubuserconte
|
|
23
23
|
|
24
24
|
h2. Gebrauchte Abkürzungen und Schlüsselworte
|
25
25
|
|
26
|
-
-
|
27
|
-
-
|
28
|
-
-
|
29
|
-
-
|
30
|
-
-
|
31
|
-
-
|
32
|
-
-
|
33
|
-
- pro compresso obducto := pro Dragée
|
34
|
-
- pro compresso := pro Tablette
|
35
|
-
- pro praeparatione := pro Präparat
|
36
|
-
- ad pulverem := zum Pulver hinzufügen
|
37
|
-
- pro charta := pro Pulver Briefchen
|
26
|
+
- DER := DrugEthanol Ratio
|
27
|
+
- Diluens := Verdünnungsmittel
|
28
|
+
- Solutio reconstituta := angefertigte Lösung
|
29
|
+
- Solvens (i.m.) := Lösungsmittel (intramuskulär)
|
30
|
+
- Solvens (i.v.) := Lösungsmittel (intravenös)
|
31
|
+
- Solvens := Lösungsmittel
|
32
|
+
- ad emulsionem := zur Herstellung einer Emulsion
|
38
33
|
- ad globulos := zu den Vaginalkugeln
|
39
|
-
-
|
40
|
-
- solvens (i.v.): aqua ad iniectabilia := Lösungsmittel (intravenös): Wasser zu Injektionszwecken
|
34
|
+
- ad pulverem := zum Pulver hinzufügen
|
41
35
|
- ad solutionem := füge zur Lösung hinzu
|
42
|
-
-
|
43
|
-
- aqua q.s. ad := genügend Wasser zu
|
44
|
-
- saccharum ad := Zucker hinzufügen zu
|
36
|
+
- ad suspensionem := zur Herstellung einer Suspension
|
45
37
|
- aether q.s. := genügend Äther/Aether/Ether
|
38
|
+
- ana partes := zu gleichen Teilen
|
39
|
+
- antiox. := Antioxidans (Oxidationshemmer)
|
46
40
|
- aqua ad iniectabilia := Wasser zu Injektionszwecken
|
41
|
+
- aqua ad iniectabilia q.s. ad solutionem := genügend steriles Wasser zur Lösung/zum Lösen
|
42
|
+
- aqua ad iniectabilia q.s. ad solutionem pro := wie oben, jedoch für (pro) eine bestimmte Menge (oder best. Volumen)
|
43
|
+
- aqua ad solutionem pro := Wasser zur Herstellung einer Lösung von …...
|
44
|
+
- aqua q.s. := genügend Wasser ...
|
45
|
+
- aqua q.s. ad := entsprechende Menge Wasser für ...
|
46
|
+
- aqua q.s. ad emulsionem pro := genügende Menge Wasser zur Herstellung der … best. Menge …. an Emulsion
|
47
|
+
- aqua q.s. ad gelatum pro := genügend Wasser zur Herstellung eines Gel
|
48
|
+
- aqua q.s. ad solutionem pro := ausreichende Menge Wasser zur Herstellung einer (best. Menge/Volumen) einer Lösung
|
49
|
+
- aqua q.s. ad suspensionem pro := dito wie oben, jedoch für eine Suspension
|
50
|
+
- aquos := tdb, 52 Vorkommnisse, z.B. 53096 @Sanukehl Strep D6, homöopathische Tropfen@
|
51
|
+
- arom. := aromatisiert ?
|
52
|
+
- ca. := zirka
|
53
|
+
- color. := gefärbt
|
54
|
+
- conserv. := konserviert
|
55
|
+
- corresp. := entsprechend
|
56
|
+
- corresp. ca. := entsprechend etwa ...
|
57
|
+
- deklar. := angegeben
|
58
|
+
- doses := Dosen (Mehrzahl von Dosis)
|
59
|
+
- doses pro vase := tbd (26 Vorkommnisse, z.B. 48943, @Turbuhaler, Pulver mit Applikator@
|
60
|
+
- et alia := es gibt noch andere Substanzen. Beispiel 62504 Olanzapin Sandoz Solufilm 20 mg
|
61
|
+
- et oder , := trennen Substanzen. Beispiel 29555 NaCl 11,7 % B. Braun, Zusatzampullen zu Infusionslösungen
|
62
|
+
- excipiens := Füllmittel
|
63
|
+
- excipiens ad emulsionem pro := Füllmittel zur Herstellung einer Emulsion in einer bestimmten Menge/Volumen
|
64
|
+
- excipiens ad pulverem pro := wie oben, aber für ein Pulver
|
65
|
+
- excipiens ad solutionem pro := wie oben, einfach für ein best. Volumen einer Lösung
|
66
|
+
- excipiens pro compresso := Füllmittel für eine Tablette
|
67
|
+
- excipiens pro compresso obducto := Füllmittel für ein Dragée
|
68
|
+
- excipiens pro praeparatione := Füllmittel für das Präparat (welches?)
|
69
|
+
- mineralia := Mineralien (Minralsalze)
|
70
|
+
- pro capsula := je Kapsel
|
71
|
+
- pro charta := pro Pulver Briefchen
|
72
|
+
- pro compresso := pro Tablette
|
73
|
+
- pro compresso obducto := pro Dragée
|
74
|
+
- pro dosi := je Dosis
|
75
|
+
- pro praeparatione := pro Präparat
|
76
|
+
- pro vase := tbd, 84 Vorkommnisse, z.B. 52331 @Extra Dry Cow ad us.vet., Suspension in Injektoren@
|
77
|
+
- pro vitro := tbd, je Gläschen (Ampulle? oder was?). Z.B. 55763 @Menopur, Injektionspräparat@
|
78
|
+
- q.s. := quantum satis (genügend, meist ohne Limitenangabe)
|
79
|
+
- q.s. ad := quatum satis ad (genügend für/zu/zum)
|
80
|
+
- q.s. ad pulverem pro := genügend je Pulver zu ...
|
47
81
|
- q.s. pro praeparatione := genügend für Präparat
|
48
|
-
-
|
82
|
+
- ratio := Verhältnis
|
83
|
+
- residui := tbd, übrig, aber wovon??, 24 Vorkommnisse, z.B. 58158 @Priorix-Tetra, Pulver und Lösungsmittel zur Herstellung einer Injektionslösung@
|
84
|
+
- saccharum ad := Zucker hinzufügen zu
|
85
|
+
- solvens (i.v.) aqua ad iniectabilia := Lösungsmittel (intravenös) Wasser zu Injektionszwecken
|
86
|
+
- q.s. ad pulverem pro genügend je Pulver zu …….
|
87
|
+
- ratio := Verhältnis
|
88
|
+
- residui := übrig, aber wovon??
|
89
|
+
- spag. := spagyrisches Medi, wahrscheinlich
|
90
|
+
- spec. := Spezies, Art
|
91
|
+
- spp. := Subspezies, Unterart
|
92
|
+
- ssp. := tbd, kommt einmal vor 55445 @Verintex, homöopathisch-spagyrische Lösung zur äusserlichen Anwendung@
|
93
|
+
- ut := vorgehende Substanz wird via nachstehend aufgeführte Salze(e) aufgenommen. Beispiel 54749 Supradyn Vital 50+.
|
94
|
+
- ut alia := tbd, kommt einmal vor 54749 @Supradyn Vital 50+, Filmtabletten@
|
95
|
+
- ut aqua ad iniectabilia q.s. ad emulsionem pro := in Form von genügend Wasser zur Herstellung einer best. Menge Emulsion
|
96
|
+
- var. := verschieden, Verschiedenes, ...
|
49
97
|
|
50
|
-
h2.
|
98
|
+
h2. Vorschlag für Bereinigung
|
51
99
|
|
52
100
|
* SwissmedicErrorHandler
|
53
|
-
* Corresp: als Label für Bestandteile
|
54
|
-
* corresp. für zugehörende Substanz
|
101
|
+
* Corresp: als Label für Bestandteile immer Gross schreiben
|
102
|
+
* corresp. für zugehörende Substanz, immer klein schreiben
|
103
|
+
* Namen von Präparaten und Substanzen, welche Klammern, Anführungszeichen, etc enthalten, mit einfache Anführungszeichen umgeben, z.B. @2,2'-methylen-bis(6-tert.-butyl-4-methyl-phenolum)@ -> @"2,2'-methylen-bis(6-tert.-butyl-4-methyl-phenolum)"@. Dito für Namen, welche Zahlen enthalten wie @Macrogolum 3350@
|
55
104
|
* @<@ durch @max.@ ersetzen (1 Mal)
|
56
105
|
* @mind.@ durch @min.@ ersetzen, @min.@ kommt viel häufiger vor
|
106
|
+
* Alle Bereiche wie @2.4-60 GBq@ durch @2.4-60 GBq@ ersetzen, damit das maschinelle Parsen einfacher wird. Siehe auch Bemerkung über Dosis.
|
107
|
+
|
108
|
+
h2. Vorkommende Lebensmittelfarbstoffe (E 100-199), Konservierungsstoffe (E 200-299) und Antioxidantien und Säureregulatoren (E 300-399)
|
109
|
+
|
110
|
+
E 102 Tartrazin
|
111
|
+
E 104 Chinolingelb
|
112
|
+
E 106
|
113
|
+
E 110 Gelborange S
|
114
|
+
E 120 Echtes Karmin
|
115
|
+
E 122 Azorubin
|
116
|
+
E 123 Amaranth
|
117
|
+
E 124 Cochenillerot A
|
118
|
+
E 127 Erythrosin
|
119
|
+
E 129 Allurarot AC
|
120
|
+
E 131 Patentblau V
|
121
|
+
E 132 Indigotin I
|
122
|
+
E 133 Brillantblau FCF
|
123
|
+
E 141 Kupferhaltige Komplexe der Chlorophylle, kupferhaltige Komplexe der Chlorophylline
|
124
|
+
E 142 Grün S
|
125
|
+
E 150 Zuckerkulöre
|
126
|
+
E 151 Brillantschwarz BN
|
127
|
+
E 153 Pflanzenkohle
|
128
|
+
E 160
|
129
|
+
E 171 Titandioxid
|
130
|
+
E 172 Eisenoxide und -hydroxide
|
131
|
+
E 200 Sorbinsäure
|
132
|
+
E 202 Kaliumsorbat
|
133
|
+
E 210 Benzoesäure
|
134
|
+
E 211 Natriumbenzoat
|
135
|
+
E 214 4-Hydroxybenzoesäureethylester
|
136
|
+
E 215 Natrium-4-Hydroxybenzoesäureethylester
|
137
|
+
E 216 4-Hydroxybenzoesäurepropylester (nicht zugelassen)
|
138
|
+
E 217 Natrium-4-Hydroxybenzoesäurepropylester (nicht zugelassen)
|
139
|
+
E 218 4-Hydroxybenzoesäuremethylester
|
140
|
+
E 219 Natrium-4-Hydroxybenzoesäuremethylester
|
141
|
+
E 220 Schwefeldioxid / Schweflige Säure
|
142
|
+
E 221 Natriumsulfit
|
143
|
+
E 222 Natriumhydrogensulfit
|
144
|
+
E 223 Natriumdisulfit
|
145
|
+
E 224 Kaliumdisulfit
|
146
|
+
E 281 Natriumpropionat
|
147
|
+
E 300 Ascorbinsäure
|
148
|
+
E 301 Natriumascorbat
|
149
|
+
E 304 Ascorbylpalmitat, Ascorbylstearat
|
150
|
+
E 307 Alpha-Tocopherol
|
151
|
+
E 310 Propylgallat
|
152
|
+
E 311 Octylgallat
|
153
|
+
E 312 Dodecylgallat
|
154
|
+
E 320 Butylhydroxyanisol (BHA)
|
155
|
+
E 321 Butylhydroxytoluol (BHT)
|
156
|
+
|
157
|
+
h2. mit Vorsicht zu geniessende Konservierungsstoffe
|
158
|
+
|
159
|
+
kritisch im Hinblick auf Nebenwirkungen im menschlichen Körper, sind meines Wissens folgende Stoffe:
|
160
|
+
|
161
|
+
214 PHB-Ester
|
162
|
+
215 PHB-Ethylester-Natriumsalz
|
163
|
+
218 PHB-Methylester
|
164
|
+
219 PHB-Methylester-Natriumsalz
|
165
|
+
220 Schwefeldioxid
|
166
|
+
221 Natriumsulfit
|
167
|
+
222 Natriumhydrogensulfit
|
168
|
+
223 Natriummetabisulfit
|
169
|
+
224 Kaliummetabisulfit
|
170
|
+
226 Calciumsulfit
|
171
|
+
|
172
|
+
Aber Vorsicht: Patienten können auch auf andere Zusatzstoffe reagieren - meist Reaktionen allergischer Natur. Gemeinhin treten primär gastro-intestinale Probleme auf (angefangen bei schlechtem Mundgeruch bis hin zu akuter Diarrhöe (Durchfall), Übelkeit, Kopfschmerzen, Hautausschläge, Jucken usw.).
|
173
|
+
|
174
|
+
Für Kleininder kann Banzylalkohol (z.T. auch in Schokoladewaren) schlimme Folgen haben. Darum dürfen Ampullenlösungen für die Pädiatrie NIE Benzylakohol als Konservierungsmittel enthalten!
|
data/lib/oddb2xml/builder.rb
CHANGED
@@ -698,7 +698,7 @@ module Oddb2xml
|
|
698
698
|
items[ean13] = info
|
699
699
|
xml.ARTICLE {
|
700
700
|
xml.GTIN ean13
|
701
|
-
xml.NAME info.
|
701
|
+
xml.NAME info.column_c
|
702
702
|
xml.PKG_SIZE info.pkg_size
|
703
703
|
xml.SELLING_UNITS info.selling_units
|
704
704
|
xml.MEASURE info.measure # Nur wenn Lösung wen Spalte M ml, Spritze
|
data/lib/oddb2xml/calc.rb
CHANGED
@@ -103,7 +103,7 @@ module Oddb2xml
|
|
103
103
|
@@names_without_galenic_forms = []
|
104
104
|
@@rules_counter = {}
|
105
105
|
attr_accessor :galenic_form, :unit, :pkg_size
|
106
|
-
attr_reader :name, :substances, :composition, :compositions
|
106
|
+
attr_reader :name, :substances, :composition, :compositions, :column_c
|
107
107
|
attr_reader :selling_units, :count, :multi, :measure, :addition, :scale # s.a. commercial_form in oddb.org/src/model/part.rb
|
108
108
|
def self.get_galenic_group(name, lang = 'de')
|
109
109
|
@@galenic_groups.values.collect { |galenic_group|
|
@@ -156,16 +156,32 @@ private
|
|
156
156
|
string ? string.to_s.gsub(/\s\s+/, ' ') : nil
|
157
157
|
end
|
158
158
|
public
|
159
|
-
def initialize(
|
160
|
-
@
|
159
|
+
def initialize(column_c = nil, size = nil, unit = nil, active_substance = nil, composition= nil)
|
160
|
+
@column_c = column_c ? column_c.gsub(/\s\s+/, ' ') : nil
|
161
|
+
@name, gal_form = ParseGalenicForm.from_string(column_c)
|
162
|
+
gal_form = gal_form.gsub(/\s\s+/, ' ').sub(' / ', '/') if gal_form
|
163
|
+
@galenic_form = search_galenic_info(gal_form)
|
161
164
|
@pkg_size = remove_duplicated_spaces(size)
|
162
165
|
@unit = unit
|
163
|
-
|
164
|
-
search_galenic_info
|
166
|
+
@selling_units = get_selling_units(@name, @pkg_size, @unit)
|
165
167
|
@composition = composition
|
166
168
|
@measure = unit if unit and not @measure
|
169
|
+
unless @galenic_form
|
170
|
+
parts = column_c.split(/\s+|,|\-/)
|
171
|
+
parts.each{
|
172
|
+
|part|
|
173
|
+
if idx = search_exact_galform(part)
|
174
|
+
@galenic_form = idx
|
175
|
+
break
|
176
|
+
end
|
177
|
+
}
|
178
|
+
end if column_c
|
179
|
+
if @measure and not @galenic_form
|
180
|
+
@galenic_form ||= search_exact_galform(@measure)
|
181
|
+
@galenic_form ||= search_exact_galform(@measure.sub('(n)', 'n'))
|
182
|
+
end
|
183
|
+
handle_unknown_galform(gal_form)
|
167
184
|
@measure = @galenic_form.description if @galenic_form and not @measure
|
168
|
-
@galenic_form ||= @@galenic_forms[UnknownGalenicForm]
|
169
185
|
|
170
186
|
unless composition
|
171
187
|
@compositions = []
|
@@ -193,9 +209,6 @@ public
|
|
193
209
|
galenic_group ? galenic_group.description : ''
|
194
210
|
]
|
195
211
|
end
|
196
|
-
def galenic_form__xxx
|
197
|
-
@galenic_form.description
|
198
|
-
end
|
199
212
|
private
|
200
213
|
|
201
214
|
def update_rule(rulename)
|
@@ -291,63 +304,49 @@ public
|
|
291
304
|
return 1
|
292
305
|
end
|
293
306
|
end
|
294
|
-
|
295
|
-
def
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
307
|
+
|
308
|
+
def search_exact_galform(name)
|
309
|
+
return nil unless name
|
310
|
+
if idx = @@galenic_forms.values.find{|x| x.descriptions['de'] and x.descriptions['de'].downcase.eql?(name.downcase) } or
|
311
|
+
idx = @@galenic_forms.values.find{|x| x.descriptions['fr'] and x.descriptions['fr'].downcase.eql?(name.downcase) } or
|
312
|
+
idx = @@galenic_forms.values.find{|x| x.descriptions['en'] and x.descriptions['en'].downcase.eql?(name.downcase) }
|
313
|
+
return idx
|
301
314
|
end
|
315
|
+
return nil
|
302
316
|
end
|
303
|
-
def search_galenic_info
|
304
|
-
@substances = nil
|
305
|
-
@substances = @composition.split(/\s*,(?!\d|[^(]+\))\s*/u).collect { |name| ParseUtil.capitalize(name) }.uniq if @composition
|
306
317
|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
@@names_without_galenic_forms << name
|
318
|
+
def handle_unknown_galform(gal_form)
|
319
|
+
return if @galenic_form
|
320
|
+
if gal_form
|
321
|
+
@galenic_form = GalenicForm.new(0, {'de' => remove_duplicated_spaces(gal_form.gsub(' +', ' '))}, @@galenic_forms[UnknownGalenicForm] )
|
322
|
+
@@new_galenic_forms << gal_form
|
313
323
|
else
|
314
|
-
|
324
|
+
@galenic_form = @@galenic_forms[UnknownGalenicForm]
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def search_galenic_info(gal_form)
|
329
|
+
if idx = search_exact_galform(gal_form)
|
330
|
+
return idx
|
331
|
+
end
|
332
|
+
if gal_form and gal_form.index(',')
|
333
|
+
parts = gal_form.split(/\s+|,/)
|
334
|
+
parts.each{
|
315
335
|
|part|
|
316
|
-
|
317
|
-
|
318
|
-
# puts "oid #{UnknownGalenicForm} #{@galenic_form.oid} for #{name}"
|
319
|
-
break unless @galenic_form.oid == UnknownGalenicForm
|
320
|
-
if @galenic_form.oid == UnknownGalenicForm
|
321
|
-
@galenic_form = GalenicForm.new(0, {'de' => remove_duplicated_spaces(form_name.gsub(' +', ' '))}, @@galenic_forms[UnknownGalenicForm] )
|
322
|
-
@@new_galenic_forms << form_name
|
336
|
+
if idx = search_exact_galform(part)
|
337
|
+
return idx
|
323
338
|
end
|
324
339
|
}
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
res = [@pkg_size]
|
330
|
-
else
|
331
|
-
res = @pkg_size ? @pkg_size.split(/x/i) : []
|
332
|
-
if res.size >= 1
|
333
|
-
@count = res[0].to_i
|
334
|
-
else
|
335
|
-
@count = 1
|
340
|
+
elsif gal_form
|
341
|
+
if gal_form.eql?('capsule')
|
342
|
+
idx = search_exact_galform('capsules')
|
343
|
+
return idx
|
336
344
|
end
|
337
|
-
|
338
|
-
|
339
|
-
if res.size >= 2
|
340
|
-
if (result = Calc.check_for_value_and_units(res[1].strip)) != nil
|
341
|
-
@multi = result[1].to_f
|
342
|
-
else
|
343
|
-
@multi = res[1].to_i
|
345
|
+
if idx = search_exact_galform(gal_form)
|
346
|
+
return idx
|
344
347
|
end
|
345
|
-
|
346
|
-
@multi = 1
|
348
|
+
return nil
|
347
349
|
end
|
348
|
-
@addition = 0
|
349
|
-
@scale = 1
|
350
|
-
@selling_units = get_selling_units(form_name, @pkg_size, @unit)
|
351
350
|
end
|
352
351
|
end
|
353
352
|
end
|
@@ -96,8 +96,7 @@ class CompositionParser < Parslet::Parser
|
|
96
96
|
rule(:words_nested) { one_word.repeat(1) >> in_parent.maybe >> space? >> one_word.repeat(0) }
|
97
97
|
# dose
|
98
98
|
# 150 U.I. hFSH et 150 U.I. hLH
|
99
|
-
rule(:
|
100
|
-
(
|
99
|
+
rule(:units) {
|
101
100
|
str('cm²') |
|
102
101
|
str('g/dm²') |
|
103
102
|
str('g/l') |
|
@@ -118,6 +117,7 @@ class CompositionParser < Parslet::Parser
|
|
118
117
|
str('kJ') |
|
119
118
|
str('G') |
|
120
119
|
str('g') |
|
120
|
+
str('I.E.') |
|
121
121
|
str('l') |
|
122
122
|
str('µl') |
|
123
123
|
str('U. Ph. Eur.') |
|
@@ -146,8 +146,8 @@ class CompositionParser < Parslet::Parser
|
|
146
146
|
str('% m/m') |
|
147
147
|
str('% m/m') |
|
148
148
|
str('%')
|
149
|
-
).as(:unit)
|
150
149
|
}
|
150
|
+
rule(:dose_unit) { units.as(:unit) }
|
151
151
|
rule(:qty_range) { (number >> space? >> (str('+/-') | str(' - ') | str(' -') | str('-') | str('±') ) >> space? >> number).as(:qty_range) }
|
152
152
|
rule(:qty_unit) { dose_qty >> (space >> dose_unit).maybe }
|
153
153
|
rule(:dose_qty) { number.as(:qty) }
|
@@ -434,6 +434,104 @@ class CompositionParser < Parslet::Parser
|
|
434
434
|
excipiens.as(:composition) |
|
435
435
|
space.repeat(3)
|
436
436
|
}
|
437
|
+
|
437
438
|
root :expression_comp
|
438
439
|
end
|
439
440
|
|
441
|
+
class GalenicFormParser < CompositionParser
|
442
|
+
|
443
|
+
rule(:prepation_separator) { str(', ') | str("\n") }
|
444
|
+
|
445
|
+
rule(:prepation_name) { ((prepation_separator|lparen).absent? >> any).repeat(1)
|
446
|
+
}
|
447
|
+
rule(:dose_with_pro) {
|
448
|
+
( match('[0-9a-zA-Z]').repeat(1) >>
|
449
|
+
str('/') >>
|
450
|
+
match('[0-9a-zA-Z\'%]').repeat(1)
|
451
|
+
).maybe
|
452
|
+
}
|
453
|
+
|
454
|
+
rule(:gal_form) {
|
455
|
+
qty_unit_silent.maybe >>
|
456
|
+
((( str("\n") # |
|
457
|
+
str(',') >> space? >> qty_unit_silent |
|
458
|
+
digits >> str('%')
|
459
|
+
).absent? >> any).repeat(1) >>
|
460
|
+
(lparen >> (rparen.absent? >> any).repeat(1) >> rparen).maybe
|
461
|
+
).as(:galenic_form) >>
|
462
|
+
space?
|
463
|
+
|
464
|
+
}
|
465
|
+
|
466
|
+
rule(:standard_galenic) {
|
467
|
+
prepation_name.as(:prepation_name) >> space? >>
|
468
|
+
prepation_separator >> space? >>
|
469
|
+
(name_without_parenthesis >> qty_unit_silent >> prepation_separator).maybe >>
|
470
|
+
(qty_unit_silent >> space?).maybe >>
|
471
|
+
(dose_with_pro >> space? >> str(',') >> space?).maybe >>
|
472
|
+
gal_form >> space?
|
473
|
+
}
|
474
|
+
|
475
|
+
rule(:qty_unit_silent) { number >> space >> units }
|
476
|
+
rule(:name_then_dose) { ((space.absent? >> any).repeat(1) >>
|
477
|
+
space >> qty_unit_silent).as(:prepation_name) >> space?.as(:galenic_form)
|
478
|
+
}
|
479
|
+
|
480
|
+
rule(:only_name) { any.repeat(1).as(:prepation_name) >> space?.as(:galenic_form)
|
481
|
+
}
|
482
|
+
|
483
|
+
rule(:name_comma_gal_form) { (space.absent? >> any).repeat(1).as(:prepation_name) >>
|
484
|
+
comma >> space >>
|
485
|
+
any.repeat(1).as(:galenic_form)
|
486
|
+
}
|
487
|
+
rule(:simple_name) { ((match(["a-zA-Z0-9,%"]) | str('-') | umlaut).repeat(1)) >>
|
488
|
+
(lparen >> (rparen.absent? >> any.repeat(1)) >> rparen).maybe
|
489
|
+
}
|
490
|
+
rule(:name_gal_form) { # e.g. Dicloabak 0,1% Augentropfen or 35 Clear-Flex 3,86 % Peritonealdialyselösung
|
491
|
+
(simple_name >> space).repeat(1).as(:prepation_name) >>
|
492
|
+
space? >>
|
493
|
+
(dose_with_pro >> space?).maybe >>
|
494
|
+
(digits.absent? >> gal_form) >> space?
|
495
|
+
}
|
496
|
+
|
497
|
+
rule(:name_without_comma_gal_form) { # Sulfure de Rhénium (186Re)-RE-186-MM-1 Cis bio International
|
498
|
+
((str(', ')| str(',') >> match(['A-Z'])).absent? >> any).repeat(1).as(:prepation_name) >>
|
499
|
+
comma >> space? >>
|
500
|
+
gal_form >> space?
|
501
|
+
}
|
502
|
+
|
503
|
+
# Phytopharma foie et bile capsules/Leber-Galle Kapseln
|
504
|
+
rule(:leber_gallen_kapseln) { ((str('/Leber-Galle Kapseln').absent? >> any).repeat(1)).as(:prepation_name) >>
|
505
|
+
str('/') >> any.repeat(1).as(:galenic_form) >>
|
506
|
+
space?
|
507
|
+
}
|
508
|
+
# Plak-out Spray 0,1 %
|
509
|
+
rule(:plak_out_spray) { str('Plak-out Spray 0,1 %').as(:prepation_name) >>
|
510
|
+
space? >> str('dummy').maybe.as(:galenic_form) >> space?
|
511
|
+
}
|
512
|
+
rule(:galenic) {
|
513
|
+
plak_out_spray |
|
514
|
+
leber_gallen_kapseln |
|
515
|
+
standard_galenic |
|
516
|
+
name_comma_gal_form |
|
517
|
+
name_then_dose >> space? |
|
518
|
+
name_without_comma_gal_form |
|
519
|
+
name_gal_form |
|
520
|
+
only_name >> space? |
|
521
|
+
space?
|
522
|
+
}
|
523
|
+
|
524
|
+
# for debugging purposes only
|
525
|
+
rule(:galenicD) {
|
526
|
+
plak_out_spray.as(:plak_out_spray) |
|
527
|
+
leber_gallen_kapseln.as(:leber_gallen_kapseln) |
|
528
|
+
standard_galenic.as(:standard_galenic) |
|
529
|
+
name_comma_gal_form.as(:name_comma_gal_form) |
|
530
|
+
name_then_dose.as(:name_then_dose) >> space? |
|
531
|
+
name_without_comma_gal_form.as(:name_without_comma_gal_form) |
|
532
|
+
name_gal_form.as(:name_gal_form) |
|
533
|
+
only_name.as(:only_name) >> space? |
|
534
|
+
space?
|
535
|
+
}
|
536
|
+
root :galenic
|
537
|
+
end
|
@@ -83,6 +83,7 @@ module ParseUtil
|
|
83
83
|
comps << ParseComposition.new(composition_text.split(/,|:|\(/)[0]) if comps.size == 0
|
84
84
|
comps
|
85
85
|
end
|
86
|
+
|
86
87
|
end
|
87
88
|
|
88
89
|
class IntLit < Struct.new(:int)
|
@@ -426,3 +427,46 @@ class ParseComposition
|
|
426
427
|
return result
|
427
428
|
end
|
428
429
|
end
|
430
|
+
|
431
|
+
class GalenicFormTransformer < CompositionTransformer
|
432
|
+
|
433
|
+
rule( :preparation_name => simple(:preparation_name),
|
434
|
+
:galenic_form => simple(:preparation_name),
|
435
|
+
) {
|
436
|
+
|dictionary|
|
437
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: dictionary #{dictionary}" if VERBOSE_MESSAGES
|
438
|
+
binding.pry
|
439
|
+
name = dictionary[:preparation_name] ? dictionary[:preparation_name].to_s : nil
|
440
|
+
form = dictionary[:galenic_form] ? dictionary[:galenic_form].to_s : nil
|
441
|
+
# name, form
|
442
|
+
}
|
443
|
+
end
|
444
|
+
|
445
|
+
class ParseGalenicForm
|
446
|
+
def ParseGalenicForm.from_string(string)
|
447
|
+
return nil if string == nil
|
448
|
+
stripped = string.gsub(/^"|["\n]+$/, '')
|
449
|
+
return nil unless stripped
|
450
|
+
puts "ParseGalenicForm.from_string #{string}" if VERBOSE_MESSAGES # /ng-tr/.match(Socket.gethostbyname(Socket.gethostname).first)
|
451
|
+
|
452
|
+
parser = GalenicFormParser.new
|
453
|
+
transf = GalenicFormTransformer.new
|
454
|
+
begin
|
455
|
+
if defined?(RSpec)
|
456
|
+
ast = transf.apply(parser.parse_with_debug(string))
|
457
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: ==> " if VERBOSE_MESSAGES
|
458
|
+
pp ast if VERBOSE_MESSAGES
|
459
|
+
else
|
460
|
+
ast = transf.apply(parser.parse(string))
|
461
|
+
end
|
462
|
+
rescue Parslet::ParseFailed => error
|
463
|
+
@@errorHandler.nrParsingErrors += 1
|
464
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__}: failed parsing ==> #{string}"
|
465
|
+
return nil
|
466
|
+
end
|
467
|
+
return [] unless ast
|
468
|
+
form = ast[:galenic_form] ? ast[:galenic_form].to_s.sub(/^\/\s+/, '') : nil
|
469
|
+
name = ast[:prepation_name] ? ast[:prepation_name].to_s.strip : nil
|
470
|
+
return [name, form]
|
471
|
+
end
|
472
|
+
end
|
data/lib/oddb2xml/version.rb
CHANGED