我在正则表达式方面的技能充其量是微不足道的。但是,我有一项任务需要阅读医学类型的文本,并标记不同类型的单词。此外,我需要确定该术语是否被否定。似乎有一组用 Python 编写并移植到 Java 的例程来执行我需要的类型的事情。它们被称为 Context/Negex,可以在这里找到;谷歌代码 Negex 项目
我可以阅读 Java,并且我了解他们正在尝试做的一些事情。我的理解是他们对句子进行术语扫描以查找术语标记术语,然后遍历一组“否定短语”并标记否定术语,并将原始术语标记更改为否定。
我的第一个问题,有人知道这种例程的 Oracle 端口吗?(一种选择是将 java 版本实现为 Oracle Java 存储过程,但我会发现很难修改和支持)。如果没有,我有一个关于正则表达式的问题;
问题:在没有嵌套的情况下替换先前替换的子集。
假设我有一个包含的字符串;
狗 大象 狗 猫 猫 狗 老鼠
然后我想标记两个短语
1) dog cat
2) dog
编辑:需要将 dog 作为一个离散的词来处理,并且不会像下面那样匹配 dogfish 或 fishdog;
狗 象 狗 猫 猫 狗 狗鱼 鱼狗 鼠标
我会用“dog cat”替换所有“dog cat”;
dog elephant <term id=123 type=pos>dog cat</term> cat dog mouse
我现在需要替换所有术语“狗”,除了已经在任何以“”开头的标签中的“狗”产生:
<term id=456 type=pos>dog</term> elephant <term id=123 type=pos>dog cat</term> cat <term id=456 type=pos>dog</term> mouse
正则表达式可以做到这一点吗?如果是这样,正则表达式会导致 regexp_replace 忽略“”标签中的任何内容?
我实施了以下概述的方法:
FUNCTION ANNOTATE_ONE_TERM(IN_TEXT IN VARCHAR2, SEARCH_TERM IN VARCHAR2, TERM_TYPE IN VARCHAR2, RECORD_ID IN NUMBER) RETURN CLOB
IS
REGEX_SEARCH VARCHAR2(512);
REGEX_REPLACE VARCHAR2(512);
BEGIN
REGEX_SEARCH := '((<TERM.*?</TERM>|[^<])*?)(^|\W)('|| SEARCH_TERM ||')($|\W)';
REGEX_REPLACE := '\1 <TERM ID='|| TO_CHAR(RECORD_ID)||' TYPE=' || TERM_TYPE ||'>'|| SEARCH_TERM ||'</TERM> ';
DBMS_OUTPUT.PUT_LINE('REGEX_SEARCH = ' || REGEX_SEARCH);
DBMS_OUTPUT.PUT_LINE('REGEX_REPLACE = ' || REGEX_REPLACE);
RETURN TRIM(REGEXP_REPLACE(IN_TEXT, REGEX_SEARCH, REGEX_REPLACE,1,0,'in'));
END ANNOTATE_ONE_TERM;
它适用于示例文本,但是当我尝试使用更简单的字符串时;
SELECT ANNOTATE_ONE_TERM(ANNOTATE_ONE_TERM(UPPER('elephant dog cat cat dogfish fishdog mouse'), 'DOG CAT', 'POS', 123),'DOG', 'POS',456)
FROM DUAL;
我最终得到;
ELEPHANT <TERM ID=123 TYPE=POS <TERM ID=456 TYPE=POS>DOG</TERM> CAT</TERM> CAT DOGFISH FISHDOG MOUSE
它似乎吃了一个尾随的“>”并嵌套了一个标签。
感谢所有额外的帮助。