Regex 在Oracle(PL/SQL)中,在正则表达式中识别单词最有效的方法是什么?

Regex 在Oracle(PL/SQL)中,在正则表达式中识别单词最有效的方法是什么?,regex,oracle,plsql,oracle11g,Regex,Oracle,Plsql,Oracle11g,编辑:我应该是具体的,我需要在PL/SQL中这样做,更具体地说是在包中的函数/过程中 我有一个例行程序,将处理许多(千万)CLOB寻找单词和短语。该例程目前通过删除大多数特殊字符并使用空格作为分隔符进行优化。显然,我需要至少包含一部分特殊字符,以使文本在后期处理时更具可读性。该子集是 ()*+./ 我开始重写程序。我的第一个代码是能够数数单词,这就是我想到的 SELECT REGEXP_COUNT(REGEXP_REPLACE('THIS IS (A TEST) OF/SPECIAL 20.5

编辑:我应该是具体的,我需要在PL/SQL中这样做,更具体地说是在包中的函数/过程中

我有一个例行程序,将处理许多(千万)CLOB寻找单词和短语。该例程目前通过删除大多数特殊字符并使用空格作为分隔符进行优化。显然,我需要至少包含一部分特殊字符,以使文本在后期处理时更具可读性。该子集是

()*+./
我开始重写程序。我的第一个代码是能够数数单词,这就是我想到的

SELECT REGEXP_COUNT(REGEXP_REPLACE('THIS IS (A TEST) OF/SPECIAL 20.5 SOME+ODD CHARACTERS.','(\(|\)|\*|\+|\. |\/)',' '),'[^ ]+') 
FROM DUAL;
我没有在这方面运行基准测试,但我怀疑这是相当低效的。有更好的办法吗

我还需要在代码中使用regexp\u replace和regexp\u子字符串。我现有的代码就是这样做的

REGEXP_REPLACE(REGEXP_SUBSTR(TEMP_TEXT,'[^ ]+',1,ORDINAL_POSITION),'(\.$|^\(|\)$)','')
UPPER(REGEXP_SUBSTR(TERM,'[^ ]+',1,CURRENT_COUNT))

注意,前面的代码实际处理了“.”和部分处理了“/”

您是否考虑过将其视为lexer而不是字符串函数的集合?一次处理一个字符可能更好

构建有限自动机需要更多的工作,但会给您更多的控制,并且比正则表达式更快。这也会帮助你更清楚地思考你的问题。例如,它会让您意识到识别“什么是空间”不是一个简单的问题,许多工具会以不同的方式进行识别

正则表达式方法可能不适用于实际CLOB。PL/SQL函数将尽可能隐式地将CLOB转换为VARCHAR2。在测试超过32767字节的字符串之前,一切都可能正常工作。然后转换可能抛出错误、截断文本或返回错误字符


不幸的是,将CLOB转换为字符表并非易事

如果数据库字符集为UTF8,CLOB将使用UCS。UTF8和UCS之间的差异通常无关紧要,因为CLOB和VARCHAR2之间的隐式转换可以完美地处理它。但是当你被迫使用DbMSYROB.SUBR时,你可能会发现一个难题:我们通常认为的“一个字符”可能是Culb中的“两个字符”。 例如,考虑这个代码:

声明
--粤语中的“cut”字。看起来像一个拿着剑的人。
v_4_byte_utf8 varchar2(1个字符):=unistr('\d841\df79');
v_字符串varchar2(10个字符):=v_4_字节_utf8 | | v_4_字节_utf8 | | v_4_字节_utf8;
v_clob clob:=v_字符串;
开始
dbms|u output.put_line('整个字符串:'|| v|u clob);
dbms_output.put_line('第一个字符:'| | substrc(v_clob,1,1));
dbms_output.put_line('第一个字符:'| | dbms_lob.substr(v_clob,amount=>1,offset=>1));
结束;
/

整个字符串:您是否考虑过将其视为lexer而不是字符串函数的集合?一次处理一个字符可能更好

构建有限自动机需要更多的工作,但会给您更多的控制,并且比正则表达式更快。这也会帮助你更清楚地思考你的问题。例如,它会让您意识到识别“什么是空间”不是一个简单的问题,许多工具会以不同的方式进行识别

正则表达式方法可能不适用于实际CLOB。PL/SQL函数将尽可能隐式地将CLOB转换为VARCHAR2。在测试超过32767字节的字符串之前,一切都可能正常工作。然后转换可能抛出错误、截断文本或返回错误字符


不幸的是,将CLOB转换为字符表并非易事

如果数据库字符集为UTF8,CLOB将使用UCS。UTF8和UCS之间的差异通常无关紧要,因为CLOB和VARCHAR2之间的隐式转换可以完美地处理它。但是当你被迫使用DbMSYROB.SUBR时,你可能会发现一个难题:我们通常认为的“一个字符”可能是Culb中的“两个字符”。 例如,考虑这个代码:

声明
--粤语中的“cut”字。看起来像一个拿着剑的人。
v_4_byte_utf8 varchar2(1个字符):=unistr('\d841\df79');
v_字符串varchar2(10个字符):=v_4_字节_utf8 | | v_4_字节_utf8 | | v_4_字节_utf8;
v_clob clob:=v_字符串;
开始
dbms|u output.put_line('整个字符串:'|| v|u clob);
dbms_output.put_line('第一个字符:'| | substrc(v_clob,1,1));
dbms_output.put_line('第一个字符:'| | dbms_lob.substr(v_clob,amount=>1,offset=>1));
结束;
/

整个字符串:嗨,寻找单词和短语的程序是什么。我认为我们可以利用Oracle全文搜索来实现这一点。它会隐式删除大部分特殊字符,我们也可以添加自己的停止词。我创建的例程读取文本,搜索特定的单词和短语,计算它们的数量,对它们做出决定,然后对它们进行注释,将注释文本写入一个单独的区域。总体目的是扫描医学文本并从文本中提取有意义的数据。然后,我认为oracle全文搜索将是有效的。Praneth,我将研究oracle全文搜索。然而,我已经稍微简化了我正在做的事情。我需要在单个clob中搜索15000多个术语/短语。每条记录有5个CLOB,当前>10000000条记录。然后我需要寻找否定的术语/短语。完成后,我会用更小的术语表在每个CLOB上进行额外的搜索。嗨,查找单词和短语的例程是什么。我认为我们可以利用Oracle全文搜索来实现这一点。它会隐式删除大部分特殊字符,我们也可以添加自己的停止词。我创建的例程读取文本,搜索特定的单词和短语,计算它们的数量,对它们做出决定,然后对它们进行注释,将注释文本写入一个单独的区域。总体目的是扫描医学文本并提取有意义的数据