PL/SQL:通过正则表达式查找所有西里尔文(或非拉丁文)符号
Posted
技术标签:
【中文标题】PL/SQL:通过正则表达式查找所有西里尔文(或非拉丁文)符号【英文标题】:PL/SQL: Find all cyrillic (or non-latin1) signs via regex 【发布时间】:2017-10-12 12:44:15 【问题描述】:我目前正在尝试找出一种方法来输出包含任何西里尔文(或非拉丁语 1)字母的表中所有行的 ID,无论它们位于哪一列 我继承了一个脚本,该脚本使用游标遍历表和列,并使用 unistr() 通过正则表达式语句搜索西里尔符号,但我无法弄清楚为什么它似乎不再在我们的 oracle 上工作12分贝
声明如下:
stmt := 'select ID from '||table_name || ' where regexp_LIKE('||table_name||'.'||column_name||','||stmt_template|| ')';
table_name 和 column name 应该是自解释的,stmt_template 是前面定义的模板,包含我的问题。 'stmt' 的用法如下(并且有效):
OPEN stmt_cursor for stmt;
LOOP [some code]
stmt_template 定义如下,总是给我一个错误
stmt_template VARCHAR(32767) := '^[''||unistr(''\20AC'')||unistr(''\1EF8'')||''-''||unistr(''\1EF9'')||unistr(''\1EF2'')||''-''||unistr(''\1EF3'')||unistr(''\1EE4'')||''-''||unistr(''\1EE5'')||unistr(''\1ED6'')||''-''||unistr(''\1ED7'')||unistr(''\1ECA'')||''-''||unistr(''\1ECF'')||unistr(''\1EC4'')||''-''||unistr(''\1EC5'')||unistr(''\1EBD'')||unistr(''\1EAA'')||''-''||unistr(''\1EAC'')||unistr(''\1EA0'')||''-''||unistr(''\1EA1'')||unistr(''\1E9E'')||unistr(''\1E9B'')||unistr(''\1E8C'')||''-''||unistr(''\1E93'')||unistr(''\1E80'')||''-''||unistr(''\1E85'')||unistr(''\1E6A'')||''-''||unistr(''\1E6B'')||unistr(''\1E60'')||''-''||unistr(''\1E63'')||unistr(''\1E56'')||''-''||unistr(''\1E57'')||unistr(''\1E44'')||''-''||unistr(''\1E45'')||unistr(''\1E40'')||''-''||unistr(''\1E41'')||unistr(''\1E30'')||''-''||unistr(''\1E31'')||unistr(''\1E24'')||''-''||unistr(''\1E27'')||unistr(''\1E1E'')||''-''||unistr(''\1E21'')||unistr(''\1E10'')||''-''||unistr(''\1E11'')||unistr(''\1E0A'')||''-''||unistr(''\1E0B'')||unistr(''\1E02'')||''-''||unistr(''\1E03'')||unistr(''\0292'')||unistr(''\0259'')||unistr(''\022A'')||''-''||unistr(''\0233'')||unistr(''\01FA'')||''-''||unistr(''\021F'')||unistr(''\01F7'')||unistr(''\01F4'')||''-''||unistr(''\01F5'')||unistr(''\01E2'')||''-''||unistr(''\01EF'')||unistr(''\01DE'')||''-''||unistr(''\01DF'')||unistr(''\01CD'')||''-''||unistr(''\01D4'')||unistr(''\01BF'')||unistr(''\01B7'')||unistr(''\01AF'')||''-''||unistr(''\01b0'')||unistr(''\01A0'')||''-''||unistr(''\01A1'')||unistr(''\018F'')||unistr(''\0187'')||''-''||unistr(''\0188'')||unistr(''\0134'')||''-''||unistr(''\017f'')||unistr(''\00AE'')||''-''||unistr(''\0131'')||unistr(''\00A1'')||''-''||unistr(''\00AC'')||unistr(''\0009'')||unistr(''\000A'')||unistr(''\000D'')||unistr(''\0020'')||''-''||unistr(''\007E'')||'']*$'')';
这应该是在搜索一长串西里尔字母和其他特殊字符,尽管它会抛出以下内容:
ORA-00936: missing expression
我已经尝试使用搜索所有不在 ascii 表中的内容
stmt_template VARCHAR(32767) :='''[^-~]''';
虽然这似乎没有给我准备的测试元组(使用一些西里尔字符以及 € 符号等),但有些行不包含任何“非法”字符
stmt_template VARCHAR(32767) := '''[^.' || CHR (1) || '-' || CHR (255) || ']''';
也不起作用,因为它给了我与上述相同的效果
谁能帮我找出我的错误/错别字或第一个正则表达式语句中的任何错误?
如果您需要更多信息,请提前告诉我,谢谢
【问题讨论】:
【参考方案1】:您的陈述评估为:
select ID from table_name where regexp_LIKE(table_name.column_name,,'^['||unistr('\20AC')||unistr('\1EF8')||'-'||unistr('\1EF9')||unistr('\1EF2')||'-'||unistr('\1EF3')||unistr('\1EE4')||'-'||unistr('\1EE5')||unistr('\1ED6')||'-'||unistr('\1ED7')||unistr('\1ECA')||'-'||unistr('\1ECF')||unistr('\1EC4')||'-'||unistr('\1EC5')||unistr('\1EBD')||unistr('\1EAA')||'-'||unistr('\1EAC')||unistr('\1EA0')||'-'||unistr('\1EA1')||unistr('\1E9E')||unistr('\1E9B')||unistr('\1E8C')||'-'||unistr('\1E93')||unistr('\1E80')||'-'||unistr('\1E85')||unistr('\1E6A')||'-'||unistr('\1E6B')||unistr('\1E60')||'-'||unistr('\1E63')||unistr('\1E56')||'-'||unistr('\1E57')||unistr('\1E44')||'-'||unistr('\1E45')||unistr('\1E40')||'-'||unistr('\1E41')||unistr('\1E30')||'-'||unistr('\1E31')||unistr('\1E24')||'-'||unistr('\1E27')||unistr('\1E1E')||'-'||unistr('\1E21')||unistr('\1E10')||'-'||unistr('\1E11')||unistr('\1E0A')||'-'||unistr('\1E0B')||unistr('\1E02')||'-'||unistr('\1E03')||unistr('\0292')||unistr('\0259')||unistr('\022A')||'-'||unistr('\0233')||unistr('\01FA')||'-'||unistr('\021F')||unistr('\01F7')||unistr('\01F4')||'-'||unistr('\01F5')||unistr('\01E2')||'-'||unistr('\01EF')||unistr('\01DE')||'-'||unistr('\01DF')||unistr('\01CD')||'-'||unistr('\01D4')||unistr('\01BF')||unistr('\01B7')||unistr('\01AF')||'-'||unistr('\01b0')||unistr('\01A0')||'-'||unistr('\01A1')||unistr('\018F')||unistr('\0187')||'-'||unistr('\0188')||unistr('\0134')||'-'||unistr('\017f')||unistr('\00AE')||'-'||unistr('\0131')||unistr('\00A1')||'-'||unistr('\00AC')||unistr('\0009')||unistr('\000A')||unistr('\000D')||unistr('\0020')||'-'||unistr('\007E')||']*$'))
去掉了正则表达式的内容后看起来像:
REGEXP_LIKE(table_name.column_name,,'your regex...'))
您需要删除正则表达式字符串开头的重复逗号和末尾重复的右圆括号。
【讨论】:
哦,谢谢,实际上早先已修复,但之后它仍然给我同样的错误,将编辑帖子!【参考方案2】:将stmt_template
的定义更改为
stmt_template VARCHAR(32767) := '^[''''||unistr(''\20AC'')||unistr(''\1EF8'')||''-''||
unistr(''\1EF9'')||unistr(''\1EF2'')||''-''||
unistr(''\1EF3'')||unistr(''\1EE4'')||''-''||
unistr(''\1EE5'')||unistr(''\1ED6'')||''-''||
unistr(''\1ED7'')||unistr(''\1ECA'')||''-''||
unistr(''\1ECF'')||unistr(''\1EC4'')||''-''||
unistr(''\1EC5'')||unistr(''\1EBD'')||unistr(''\1EAA'')||''-''||
unistr(''\1EAC'')||unistr(''\1EA0'')||''-''||
unistr(''\1EA1'')||unistr(''\1E9E'')||unistr(''\1E9B'')||unistr(''\1E8C'')||''-''||
unistr(''\1E93'')||unistr(''\1E80'')||''-''||
unistr(''\1E85'')||unistr(''\1E6A'')||''-''||
unistr(''\1E6B'')||unistr(''\1E60'')||''-''||
unistr(''\1E63'')||unistr(''\1E56'')||''-''||
unistr(''\1E57'')||unistr(''\1E44'')||''-''||
unistr(''\1E45'')||unistr(''\1E40'')||''-''||
unistr(''\1E41'')||unistr(''\1E30'')||''-''||
unistr(''\1E31'')||unistr(''\1E24'')||''-''||
unistr(''\1E27'')||unistr(''\1E1E'')||''-''||
unistr(''\1E21'')||unistr(''\1E10'')||''-''||
unistr(''\1E11'')||unistr(''\1E0A'')||''-''||
unistr(''\1E0B'')||unistr(''\1E02'')||''-''||
unistr(''\1E03'')||unistr(''\0292'')||unistr(''\0259'')||unistr(''\022A'')||''-''||
unistr(''\0233'')||unistr(''\01FA'')||''-''||
unistr(''\021F'')||unistr(''\01F7'')||unistr(''\01F4'')||''-''||
unistr(''\01F5'')||unistr(''\01E2'')||''-''||
unistr(''\01EF'')||unistr(''\01DE'')||''-''||
unistr(''\01DF'')||unistr(''\01CD'')||''-''||
unistr(''\01D4'')||unistr(''\01BF'')||unistr(''\01B7'')||unistr(''\01AF'')||''-''||
unistr(''\01b0'')||unistr(''\01A0'')||''-''||
unistr(''\01A1'')||unistr(''\018F'')||unistr(''\0187'')||''-''||
unistr(''\0188'')||unistr(''\0134'')||''-''||
unistr(''\017f'')||unistr(''\00AE'')||''-''||
unistr(''\0131'')||unistr(''\00A1'')||''-''||
unistr(''\00AC'')||unistr(''\0009'')||unistr(''\000A'')||unistr(''\000D'')||unistr(''\0020'')||''-''||
unistr(''\007E'')||'''']*$'')';
原来的定义似乎在字符串的开头和结尾留下了一个不平衡的单引号。我仍然不确定这是否会起作用,因为在字符串的最后似乎有一个不匹配的右括号,但它可能会更好。
祝你好运。
【讨论】:
【参考方案3】:这应该会为您提供不在 ascii-7 范围 chr(32) - chr(127) 内的数据:
select col1
from my_table
where regexp_like(col1, '[^'||chr(32)||'-'||chr(127)||']')
请注意,我将控制字符(小于 12 月 32 日)和扩展 ascii (> 127) 排除在我的范围内。
【讨论】:
以上是关于PL/SQL:通过正则表达式查找所有西里尔文(或非拉丁文)符号的主要内容,如果未能解决你的问题,请参考以下文章
在 oracle 中使用正则表达式查找 POBOX - PL/SQL