为啥当 CLOB 大小 > 4KB 时这个简单的正则表达式不起作用?

Posted

技术标签:

【中文标题】为啥当 CLOB 大小 > 4KB 时这个简单的正则表达式不起作用?【英文标题】:Why this simple regexp doesn't work when CLOB size > 4KB?为什么当 CLOB 大小 > 4KB 时这个简单的正则表达式不起作用? 【发布时间】:2014-05-10 18:04:26 【问题描述】:
declare
  c clob := '0123456789ABCDEF';
begin
  c := c||c||c||c; c := c||c||c||c;
  c := c||c||c||c; c := c||c||c||c;
  -- Now length(c) = 4096
  c := regexp_substr(c, '(.*)\1'); --ERROR:No more data to read from socket. Why?
end;

it 是错误吗?

使用varchar2 代替clob 时效果很好。

【问题讨论】:

听起来很像;警报日志是否说明服务器会话死亡的原因? SQL Fiddle 使用 11.2.0.2,所以它可能会在以后的补丁集中修复,除非你已经在使用... 我同意这有点像一个错误。但是请注意,如果将模式更改为返回较少字符 (as in this SQLFiddle) 的内容,则它可以正常工作 - 因此,似乎 REGEXP_SUBSTR 可能在返回的子字符串的长度方面存在问题。另请注意,这可能是 SQLFiddle 本身的问题。我这里没有本地 Oracle 实例可供玩弄 - 如果有人这样做并且可以报告,我相信我们都会很感激。 【参考方案1】:

我有理由相信这是 Oracle 中的一个错误,并且与使用的特定正则表达式有关。 In this SQLFiddle 我玩弄了不同长度的 CLOB,返回了不同长度的字符串,我发现的唯一正则表达式(在我非常非详尽的测试中)是 OP 提供的。 SQLFiddle 的代码是:

create table temp_output(s varchar2(4000));

declare
  c16   clob := '0123456789ABCDEF';
  c64   clob;
  c256  clob;
  c1k   clob;
  c4k   clob;
  c4kp2 clob;  -- 4096 with 'x' at each end
  c4kwx clob;  -- 4095 with 'x' at each end
  c16k  clob;
  c16kwx  clob;  -- 16k with x's embedded
  x     clob := 'x';
  d     clob;
begin
  c64  := c16  || c16  || c16  || c16;
  c256 := c64  || c64  || c64  || c64;
  c1k  := c256 || c256 || c256 || c256;
  c4k  := c1k  || c1k  || c1k  || c1k;
  c4kp2 := x || c4k || x;
  c4kwx := x || SUBSTR(c4k, 1, 4093) || x;  -- 4095 chars total
  c16k := c4k  || c4k  || c4k || c4k;
  c16kwx := c4k || x || c4k || c4k || x || c4k;

  insert into temp_output(s) values ('LENGTH(c4k)=' || LENGTH(c4k));
  insert into temp_output(s) values ('LENGTH(c16k)=' || LENGTH(c16k));

  -- d := regexp_substr(c4kp2, '(.*)\1');  -- ERROR
  -- d := regexp_substr(c4kp2, 'x.*x');  -- No error
  d := regexp_substr(c16kwx, 'x.*x');  -- No error

  insert into temp_output (s) values ('LENGTH(d)=' || LENGTH(d));
  insert into temp_output (s) values (SUBSTR(d, 1, 4000));
end;
/
select * from temp_output
/

我最初的想法是,也许正则表达式可以提取的文本数量有一个未发布的限制,但事实证明这是不正确的。

分享和享受。

【讨论】:

这个问题似乎只出现在包含冗长反向引用(超过 4K)的正则表达式中。

以上是关于为啥当 CLOB 大小 > 4KB 时这个简单的正则表达式不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

Linux内存页大小

HDFS中的数据块大小,为啥是64MB?

为啥当鼠标悬停后出现边框时 <div> 的大小会增加? CSS [重复]

线程的堆栈

为啥当我更改最大堆大小时 Eclipse 不打开?

无法在 oracle 中假脱机行大小 > 32676 的 clob 列