代码之家  ›  专栏  ›  技术社区  ›  Wernfried Domscheit

找出字符串是否只包含ASCII字符

  •  3
  • Wernfried Domscheit  · 技术社区  · 6 年前

    我需要知道一个字符串是否只包含ASCII字符。到目前为止,我使用这个regex:

    DECLARE
        str VARCHAR2(100) := 'xyz';
    BEGIN
        IF REGEXP_LIKE(str, '^[ -~]+$') THEN
            DBMS_OUTPUT.PUT_LINE('Pure ASCII');
        END IF;
    END;
    /
    
    Pure ASCII
    

    ' ' ~ 是第一个。ASCII中的最后一个字符。

    问题是,这种类似regexp的方法在某些NLS设置上失败:

    ALTER SESSION SET NLS_SORT = 'GERMAN'; 
    
    DECLARE
        str VARCHAR2(100) := 'xyz';
    BEGIN
        IF REGEXP_LIKE(str, '^[ -~]+$') THEN
            DBMS_OUTPUT.PUT_LINE('Pure ASCII');
        END IF;
    END;
    /
    
    ORA-12728: invalid range in regular expression
    ORA-06512: at line 4
    

    有人知道一个独立于当前用户NLS设置的解决方案吗?这种行为是故意的还是应该被视为bug?

    3 回复  |  直到 6 年前
        1
  •  1
  •   Matthew McPeak    6 年前

    你可以用 TRANSLATE 这样做。基本上, translate 去掉所有的ASCII可打印字符(没有那么多字符),看看你还剩下什么。

    下面是一个执行此操作的查询:

    WITH input ( p_string_to_test) AS ( 
    SELECT 'This this string' FROM DUAL UNION ALL
    SELECT 'Test this ' || CHR(7) || ' string too!' FROM DUAL UNION ALL
    SELECT 'xxx' FROM DUAL)
    SELECT p_string_to_test, 
           case when translate(p_string_to_test, 
           chr(0) || q'[ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~]', 
           chr(0)) is null then 'Yes' else 'No' END is_ascii
    FROM input;
    
    +-------------------------+----------+
    |    P_STRING_TO_TEST     | IS_ASCII |
    +-------------------------+----------+
    | This this string        | Yes      |
    | Test this  string too!  | No       |
    | xxx                     | Yes      |
    +-------------------------+----------+
    
        2
  •  1
  •   Barbaros Özhan    6 年前

    ASCII 上限为的函数 127 可用于:

    declare
        str nvarchar2(100) := '\xyz~*-=)(/&%+$#£>|"éß';
        a   nvarchar2(1);
        b   number := 0;
    begin
        for i in 1..length(str)
        loop                 
          a := substrc(str,i,1);
          b := greatest(ascii(a),b);      
        end loop;
    
        if b < 128 then  
         dbms_output.put_line('String is composed of Pure ASCII characters');
        else
         dbms_output.put_line('String has non-ASCII characters');      
        end if; 
    end;
    
        3
  •  0
  •   Wernfried Domscheit    6 年前

    我想我要这两个中的一个

    IF CONVERT(str, 'US7ASCII') = str THEN
        DBMS_OUTPUT.PUT_LINE('Pure ASCII');
    END IF;
    
    
    
    IF ASCIISTR(REPLACE(str, '\', '/')) = REPLACE(str, '\', '/') THEN
        DBMS_OUTPUT.PUT_LINE('Pure ASCII');
    END IF;