SELECT
POLINE_ID,
STRING_INDEX AS NON_PRINTABLE_LOCATION,
ASCII(REGEXP_SUBSTR(SUBSTR(DESCRIPTION, STRING_INDEX, 1), '[[:cntrl:]]', 1, 1)) AS NON_PRINTABLE_ASCII_NUMBER
FROM POLINE
CROSS JOIN (SELECT LEVEL AS STRING_INDEX
FROM DUAL
CONNECT BY LEVEL < 257) CANDIDATE_LOCATION
WHERE PONUM = 'XXX'
AND SITEID = 'YYY'
AND REGEXP_LIKE(DESCRIPTION, '[[:cntrl:]]')
AND REGEXP_INSTR(SUBSTR(DESCRIPTION, STRING_INDEX, 1), '[[:cntrl:]]', 1, 1, 0) > 0
AND STRING_INDEX <= LENGTH(DESCRIPTION)
ORDER BY 1 ASC, 2 ASC;
第二の例を使用して
まずたとえば、:
SELECT
POLINE_ID,
STRING_INDEX AS NON_PRINTABLE_LOCATION,
ASCII(SUBSTR(DESCRIPTION, STRING_INDEX, 1)) AS NON_PRINTABLE_ASCII_NUMBER
FROM POLINE
CROSS JOIN (SELECT LEVEL AS STRING_INDEX
FROM DUAL
CONNECT BY LEVEL < 257) CANDIDATE_LOCATION
WHERE PONUM = 'XXX'
AND SITEID = 'YYY'
AND REGEXP_LIKE(DESCRIPTION, '[[:cntrl:]]')
AND ASCII(SUBSTR(DESCRIPTION, STRING_INDEX, 1)) BETWEEN 1 AND 31
AND STRING_INDEX <= LENGTH(DESCRIPTION)
ORDER BY 1 ASC, 2 ASC;
我々のテストデータでは、これらのクエリは同等の出力を生成します。 Sherlock
DESCRIPTION
には2ヒット(chrs 17と23)があり、最初の64-ascii DESCRIPTION
には31ヒットとなるはずです。
結果:コメントに応えて
POLINE_ID NON_PRINTABLE_LOCATION NON_PRINTABLE_ASCII_NUMBER
1 9 23
1 56 17
2 1 1
2 2 2
2 3 3
2 4 4
2 5 5
2 6 6
2 7 7
2 8 8
2 9 9
2 10 10
2 11 11
2 12 12
2 13 13
2 14 14
2 15 15
2 16 16
2 17 17
2 18 18
2 19 19
2 20 20
2 21 21
2 22 22
2 23 23
2 24 24
2 25 25
2 26 26
2 27 27
2 28 28
2 29 29
2 30 30
2 31 31
33 rows selected.
EDITは、ここで我々は[[:cntrl:]]
と[^[:cntrl:]]
からregexp_instr
と期待できることにいくつかの工夫です。
[[:cntrl:]]
は最初の31文字のASCII文字のいずれかに一致し、[^[:cntrl:]]
は論理否定が[[:cntrl:]]
であるため、最初の31文字のASCII文字以外は一致します。
これらを比較するには、最も単純な場合は1文字だけ開始することができます(ascii #31
)。 1つの文字しかないので、結果は一致するものと見逃すもののどちらでもかまいません。今、私たちは2つ(またはそれ以上を含む場合
SELECT REGEXP_INSTR(CHR(31),'[^[:cntrl:]]',1,1,0) AS MATCH_INDEX FROM DUAL;
MATCH_INDEX
0
:[:CNTRL:] [^]否定するとミスのため
SELECT REGEXP_INSTR(CHR(31),'[[:cntrl:]]',1,1,0) AS MATCH_INDEX FROM DUAL;
MATCH_INDEX
1
しかし、0:一つは、次の試合のために1
を返すことを期待します)文字が印刷可能と印刷不能の組み合わせである場合、より多くの可能性があります。 [[:cntrl:]]
と[^[:cntrl:]]
の両方が一致しますが、異なるものにしか一致しません。 ascii #31
からascii #64#31
に移動すると、[[:cntrl:]]
が一致することが期待されます(2番目の位置に印刷できない文字があるため)が、2番目の位置に印刷不能なので2を返します。
SELECT REGEXP_INSTR(CHR(64)||CHR(31),'[[:cntrl:]]',1,1,0) AS MATCH_INDEX FROM DUAL;
MATCH_INDEX
2
そして今[^[:cntrl:]]
もは、(第1の位置)と一致する機会を持っている:
SELECT REGEXP_INSTR(CHR(64)||CHR(31),'[^[:cntrl:]]',1,1,0) AS MATCH_INDEX FROM DUAL;
MATCH_INDEX
1
印刷可能と制御文字が混在している場合は、[[:cntrl:]]
と[^[:cntrl:]]
の両方が一致することができ、彼らは異なる指数で一致します。
ありがとうございますmax092012行ごとに印刷できない文字がすべて出現するのを探しているのか、最初の出現しか見たくないのでしょうか? – alexgibbs