3

法的説明の四半期データを検証するクエリに取り組んでいます。私たちの標準は、南東の四分の一を示す「SE/4」または北西の四分の一の南東の四分の一を示す「SE/4 NW/4」のような入力です。スペースまたは文字列の終わりをチェックするために正規表現で構造化する方法に苦労しています。

これまでの正規表現を使用したサンプルデータをいくつか示します。

WITH test_data AS (
  SELECT 'NW/4' AS quarter_cd FROM dual UNION ALL --VALID
  SELECT 'E/2 SW/4' FROM dual UNION ALL           --VALID
  SELECT 'W/2' FROM dual UNION ALL                --VALID
  SELECT 'SW/4 NE/4' FROM dual UNION ALL          --VALID
  SELECT 'SW/4 NE/4 NW/4' FROM dual UNION ALL     --VALID, THEY CAN REPEAT AN UNKNOWN NUMBER OF TIMES
  SELECT 'E/2 N/2' FROM dual UNION ALL            --TECHNICALLY VALID BUT WOULD LIKE TO EXCLUDE (1/2 of 1/2 is a 1/4) -> NE/4
  SELECT 'E/2 SW/4, SE/4' FROM dual UNION ALL     --INVALID, HAS A COMMA (TWO QUARTER ENTRIES ON ONE ROW)
  SELECT 'E/2 SW/4 & SE/4' FROM dual UNION ALL    --INVALID, HAS AN AMPERSAND (TWO QUARTER ENTRIES ON ONE ROW)
  SELECT 'E/2 SW/' FROM dual UNION ALL            --INVALID, INCOMPLETE ENTRY
  SELECT 'SE/4SW/4' FROM dual UNION ALL           --INVALID, NO SPACE BETWEEN DEFINITIONS
  SELECT 'SE/2' FROM dual UNION ALL               --INVALID, SOUTHEAST HALF DOES NOT MAKE SENSE
  SELECT 'N/4' FROM dual UNION ALL                --INVALID, NORTH QUARTER DOES NOT MAKE SENSE
  SELECT 'LOT 1' FROM dual                        --INVALID, LOTS WILL BE DEALT WITH SEPARATELY
)
SELECT * FROM test_data 
WHERE regexp_like(quarter_cd, '^([NSEW]/[2]{1}|[NSEW]{2}/[4]{1})+', 'c');

私のコードの正規表現は、私の多くの試みの 1 つにすぎません。返す必要がある結果をクエリでマークしました。簡単にするために「E/2 N/2」が返されることを許可しますが、北半分の東半分は北東四半期に単純化するのが最善であるため、技術的には無効です。上記のすべての例は、私のデータの実際のエントリから抽出されました。

どんな助けでも大歓迎です。

4

2 に答える 2

2

これが私の、控えめな試みです:

select *
  from test_data
 where regexp_like(quarter_cd
        , '^((([NSEW]{1}/2)|[NS]{1}[EW]{1}/4)([[:space:]]|$))+$'
        , 'c')

E/2 N/2それは私が恐れていることを返します。

これ

  • NSEWの1つに続いて2を許可します
  • またはNSEWのいずれかとそれに続く4
  • この後にスペースまたは行末を続ける必要があります
  • これを貪欲に一致させます
  • 行末で終了する必要があります

あなたを分割することによって、[NSEW]それはNSまたはEWなどでの一致を排除します。

これがデモンストレーションするSQLフィドルです。私はあなた自身の上にいくつかの余分なケースを追加しました。これに伴う問題は、4つの半分すべてを許可することです。

このデータを検証するために正規表現を使用しないことを真剣に検討します。代わりに、PL/SQL関数を介して渡します。スペースを分割し、制限を超えないように確認する必要があるものを合計します。次に、より小さな正規表現を使用して、スペース区切り文字間のベースのデータを検証できます。

于 2012-06-19T21:51:41.430 に答える
1

このようなものがあなたが望むものを与えると思います:

SELECT * FROM 
  test_data 
WHERE 
  regexp_like(quarter_cd, 
  '^([NSEW]/[2]{1}|[NSEW]{2}/[4]{1})( [NSEW]/[2]{1}| [NSEW]{2}/[4]{1})*$', 'c');

ただし、「E2 / N2」の場合は一致します。代わりにこれを行う場合:

SELECT * FROM 
  test_data 
WHERE 
  regexp_like(quarter_cd, 
  '^([NSEW]/[2]{1}|[NSEW]{2}/[4]{1})( [NSEW]{2}/[4]{1})*$', 'c');

それは一致しませんが、最初の位置の後に [NSEW]/2 を含むケースにも一致しません。したがって、「NW/4 E/2」などと一致させる必要がある場合、これは適切ではありません... 北西地区の東半分です。

于 2012-06-19T20:47:09.237 に答える