Pyparsing: wyodrębnij zmienną długość, zmienną zawartość, zmienne podciąganie białych znaków
Muszę wyciągnąć wyniki Gleasona z płaskiego pliku ostatecznych badań diagnostycznych prostatektomii. Te wyniki zawsze zawierają słowo Gleason i dwie liczby, które sumują się do innej liczby. Ludzie pisali je przez ponad dwie dekady. Uwzględniono różne konwencje białych znaków i modyfikatorów. Poniżej znajduje się moja forma Backus-Naur i dwa przykładowe rekordy. Tylko w przypadku prostatektomii obserwujemy ponad tysiąc przypadków.
Używam pyparsingu, ponieważ uczę się pythona i nie mam miłych wspomnień z mojej bardzo ograniczonej ekspozycji na pisanie wyrażeń regularnych.
Moje pytanie: jak mogę wyrwać te stopnie Gleasona bez analizowania każdego innego opcjonalnego elementu danych, który może być lub nie być w tych ostatecznych diagnozach?
num = Word(nums)
record ::= accessionDate + accessionNumber + patMedicalRecordNum + finalDxText
accessionDate ::= num + "/" + num + "/" num
accessionNumber ::= "S" + num + "-" + num
patMedicalRecordNum ::= num + "/" + num + "-" + num + "-" + num
finalDxText ::= listOfParts + optionalComment + optionalpTNMStage
listOfParts ::= OneOrMore(part)
part ::= <multiline idiosyncratic freetext which may contain a Gleason score I want> + optionalpTNMStage
optionalComment ::= <multiline idiosyncratic freetext which may contain a Gleason score I don't want>
optionalpTNMStage ::= <multiline idiosyncratic freetext which may contain a Gleason score I don't want>
01/01/11 S11-55555 20/444-55-6666 A. PROSTATE AND SEMINAL VESICLES, PROSTATECTOMY:
- ADENOCARCINOMA.
TOTAL GLEASON SCORE: GLEASON 5+4=9
TUMOR LOCATION: BILATERAL
TUMOR QUANTITATION: 15% OF PROSTATE INVOLVED BY TUMOR
EXTRAPROSTATIC EXTENSION: PRESENT AT RIGHT POSTERIOR
SEMINAL VESICLE INVASION: PRESENT
MARGINS: UNINVOLVED
LYMPHOVASCULAR INVASION: PRESENT
PERINEURAL INVASION: PRESENT
LYMPH NODES (SPECIMENS B AND C):
NUMBER EXAMINED: 25
NUMBER INVOLVED: 1
DIAMETER OF LARGEST METASTASIS: 1.7 mm
ADDITIONAL FINDINGS: HIGH-GRADE PROSTATIC INTRAEPITHELIAL NEOPLASIA,
ACUTE AND CHRONIC INFLAMMATION, INTRADUCTAL EXTENSION OF INVASIVE
CARCINOMA
PATHOLOGIC STAGE: pT3b N1 MX
B. LYMPH NODES, RIGHT PELVIC, EXCISION:
- ONE OF SEVENTEEN LYMPH NODES POSITIVE FOR METASTASIS (1/17).
C. LYMPH NODES, LEFT PELVIC, EXCISION:
- EIGHT LYMPH NODES NEGATIVE FOR METASTASIS (0/8).
01/02/11 S11-4444 20/111-22-3333 PROSTATE AND SEMINAL VESICLES, PROSTATECTOMY:
- ADENOCARCINOMA.
GLEASON SCORE: 3 + 3 = 6 WITH TERTIARY PATTERN OF 5.
TUMOR QUANTITATION: APPROXIMATELY 10% BY VOLUME.
TUMOR LOCATION: BILATERAL.
EXTRAPROSTATIC EXTENSION: NOT IDENTIFIED.
MARGINS: NEGATIVE.
PERINEURAL INVASION: IDENTIFIED.
LYMPH-VASCULAR INVASION: NOT IDENTIFIED.
SEMINAL VESICLE/VASA DEFERENTIA INVASION: NOT IDENTIFIED.
LYMPH NODES: NONE SUBMITTED.
OTHER: HIGH GRADE PROSTATIC INTRAEPITHELIAL NEOPLASIA.
PATHOLOGIC STAGE (pTNM): pT2c NX.
Pełne ujawnienie: jestem lekarzem prowadzącym badania; to jest moja pierwsza prawdziwa praca z Pythonem. Przeczytałem Lutz Learning Python, Shaw's Learning Python the Hard Way i pracowałem nad różnymi zestawami problemów. Przejrzałem wiele pytań związanych z pyparsowaniem na tym forum, parsarsującej wiki, i kupiłem i przeczytałem artykuł Mr McGuire'a na temat Pyparsing. Być może zadaję pytanie, kiedy naprawdę powinienem powiedzieć, że stoję na „Śmiertelnej spirali frustacji, która jest tak powszechna, gdy trzeba pisać parsery” (McGuire, 17 lat)? Nie wiem Do tej pory cieszę się, że pracuję nad tym, co może być prawdziwym projektem.