SQLiteクエリで正規表現を使用するにはどうすればよいですか?


102

sqliteで正規表現を使用したいのですが、方法がわかりません。

テーブルに次のような文字列の列があります: "3,12,13,14,19,28,32"ここで「where x LIKE '3'」と入力すると、13や32などの値を含む行も取得されます、しかし私はその文字列で正確に値3を持つ行のみを取得したいと思います。

誰かがこれを解決する方法を知っていますか?


この答えは、C#でのsqliteにREGEXP機能を追加するための最善の方法ですstackoverflow.com/a/26155359/5734452
hubaishan

回答:


74

SQLite3はREGEXP演算子をサポートします:

WHERE x REGEXP <regex>

http://www.sqlite.org/lang_expr.html#regexp


3
私は簡単な方法を見つけました:それは単に\ bx \ bです。ここで、xは文字列で探す値です:)
cody

12
@DanS:演算子regex()をサポートする関数をどのように追加しますREGEXPか?デフォルトでは、ユーザー関数は追加されていません。
SK9

47
Sqliteドキュメントによると:REGEXP演算子は、regexp()ユーザー関数の特別な構文です。regexp()ユーザー関数はデフォルトでは定義されていないため、REGEXP演算子を使用すると、通常、エラーメッセージが表示されます。"regexp"というアプリケーション定義のSQL関数が実行時に追加されると、REGEXP演算子を実装するためにその関数が呼び出されます。(sqlite.org/lang_expr.html#regexp
平方根数

あなたは以下の応答からこのチェックをしようとするとエラーが出る私たちにとってstackoverflow.com/a/18484596/1585572私は、ファイル内のコードを入れて、私のFirefoxのSQLite Managerでのユーザー定義関数でそれを輸入しました。ただし、次のように少し異なる方法で呼び出す必要があります。SELECT * FROM table WHERE column regexp( "myregexp")
Tristan

112

他の人がすでに指摘したように、REGEXPは、最初に定義してデータベースにロードする必要があるユーザー定義関数を呼び出します。たぶん、いくつかのsqliteディストリビューションまたはGUIツールにはデフォルトで含まれていますが、私のUbuntuインストールには含まれていません。解決策は

sudo apt-get install sqlite3-pcre

ロード可能なモジュールにPerl正規表現を実装します /usr/lib/sqlite3/pcre.so

それを使用できるようにするには、データベースを開くたびにロードする必要があります。

.load /usr/lib/sqlite3/pcre.so

または、その行をに入れることもできます~/.sqliterc

これで、次のようにクエリできます。

SELECT fld FROM tbl WHERE fld REGEXP '\b3\b';

コマンドラインから直接クエリを実行する場合は-cmd、SQLの前にスイッチを使用してライブラリをロードできます。

sqlite3 "$filename" -cmd ".load /usr/lib/sqlite3/pcre.so" "SELECT fld FROM tbl WHERE fld REGEXP '\b3\b';"

Windowsを使用している場合は、どこかで同様の.dllファイルが利用できるはずです。


15
別の読み込みオプション:これでビューを作成しました:SELECT load_extension( '/ usr / lib / sqlite3 / pcre.so'); そうすることで、DBへのGUIベースのエントリポイント(FirefoxのSQLite Managerなど)を使用するときに、REGEXP機能をロードする方法があります。
Paulb

30

正規表現なしでそれを解決するためのハッキーな方法は where ',' || x || ',' like '%,3,%'


1
はい、そう思いましたが、毎回「、」をリードしたりフォローしたりすることはありません。とにかくありがとう:-)
cody

私はここで問題につまずかなかった-これはxが列名であるため機能するのだろうか...
cody

3
使用する必要があります',' || x || ','
Baruch

21

SQLiteには、デフォルトでは正規表現機能は含まれていません。

それはREGEXP演算子を定義しますが、あなたまたはあなたのフレームワークがと呼ばれるユーザー関数を定義しない限り、これはエラーメッセージで失敗しますregexp()。これを行う方法は、プラットフォームによって異なります。

regexp()関数を定義している場合は、次のようにカンマ区切りのリストから任意の整数を照合できます。

... WHERE your_column REGEXP "\b" || your_integer || "\b";

しかし、実際には、単一の列内のグループをカンマ区切りリストの各数値の個別の行に置き換えることでデータベース構造正規化すると、はるかに簡単に見つけることができるように見えます。次に、正規表現の代わりに演算子を使用するだけでなく、SQLが提供する結合などのより強力なリレーショナルツールを使用することもできます。=


14

REGEXPMySQLでの動作を模倣するキーワード用のPHP / PDOのSQLite UDF :

$pdo->sqliteCreateFunction('regexp',
    function ($pattern, $data, $delimiter = '~', $modifiers = 'isuS')
    {
        if (isset($pattern, $data) === true)
        {
            return (preg_match(sprintf('%1$s%2$s%1$s%3$s', $delimiter, $pattern, $modifiers), $data) > 0);
        }

        return null;
    }
);

u修飾子は、MySQLで実装されていませんが、私はそれが便利デフォルトでそれを持って見つけます。例:

SELECT * FROM "table" WHERE "name" REGEXP 'sql(ite)*';
SELECT * FROM "table" WHERE regexp('sql(ite)*', "name", '#', 's');

$dataまたは$patternNULLの場合、MySQLと同様に結果はNULLになります。


8

sqlite3を使ったpythonでの私の解決策:

   import sqlite3
   import re

   def match(expr, item):
        return re.match(expr, item) is not None

   conn = sqlite3.connect(':memory:')
   conn.create_function("MATCHES", 2, match)
   cursor = conn.cursor()
   cursor.execute("SELECT MATCHES('^b', 'busy');")
   print cursor.fetchone()[0]

   cursor.close()
   conn.close()

正規表現が一致する場合、出力は1、それ以外の場合は0になります。


5

ほぼ一年前に投稿された質問に答えるのは良いことではありません。しかし、私はSqlite自体がREGEXP関数を提供していると思う人のためにこれを書いています

sqliteで関数REGEXPを呼び出すための基本的な要件の1つは、
「アプリケーションで独自の関数を作成してから、sqliteドライバーへのコールバックリンクを提供すること」です。
そのためには、sqlite_create_function(Cインターフェイス)を使用する必要があります。詳細はこちらこちらから


4
UPDATE TableName
 SET YourField = ''
WHERE YourField REGEXP 'YOUR REGEX'

そして:

SELECT * from TableName
 WHERE YourField REGEXP 'YOUR REGEX'

4

包括的なor'ed where句は文字列の連結なしでそれを行うことができます:

WHERE ( x == '3' OR
        x LIKE '%,3' OR
        x LIKE '3,%' OR
        x LIKE '%,3,%');

4つのケースの完全一致、リストの終わり、リストの始まり、および中間リストが含まれます。

これはより冗長で、正規表現拡張を必要としません。


4

Pythonでは、conSQLiteへの接続を想定しているため、次のように記述することで必要なUDFを定義できます。

con.create_function('regexp', 2, lambda x, y: 1 if re.search(x,y) else 0)

以下に、より完全な例を示します。

import re
import sqlite3

with sqlite3.connect(":memory:") as con:
    con.create_function('regexp', 2, lambda x, y: 1 if re.search(x,y) else 0)
    cursor = con.cursor()
    # ...
    cursor.execute("SELECT * from person WHERE surname REGEXP '^A' ")


私見チェックはif x not Null and y not Null and re.search(x,y)それ以外の場合はスローされます。
pholat

2

REGEXPで正規表現を使用することもできますが、これは完全一致を行う愚かな方法です。

ただ言うべきWHERE x = '3'です。


私はそれをよりよく説明するべきでした(私の英語が下手で申し訳ありません)、私は正確な文字列ではなく、特定の正確な値のみを意味しました。とにかくありがとう!
cody

2

これを使用することを検討してください

WHERE x REGEXP '(^|,)(3)(,|$)'

xが次の場合、これは正確に3に一致します。

  • 3,12,13
  • 12,13,3
  • 12,3,13

その他の例:

WHERE x REGEXP '(^|,)(3|13)(,|$)'

これは3または13で一致します


1

この文字列のように、Android Sqliteの正規表現ではない条件を探している人がいる場合は、@ phyatt条件で括弧({})のような他の特殊文字に同じ[1,2,3,4,5]ブラケット([])を追加することを忘れないでください。

WHERE ( x == '[3]' OR
        x LIKE '%,3]' OR
        x LIKE '[3,%' OR
        x LIKE '%,3,%');

0

phpを使用している場合は、SQLite3 :: createFunctionを使用してSQLステートメントに関数を追加できます。PDO ではPDO :: sqliteCreateFunctionを使用して、ステートメント内にpreg_match関数を実装できます。

(Havaliteによってどのように行われ、その参照SQLiteのは、PHPを使用して正規表現


MySQL REGEXP関数では、パターンで区切り文字や修飾子を指定する必要はありません。
Alix Axel

0

あなたも考慮するかもしれません

WHERE x REGEXP '(^|\D{1})3(\D{1}|$)'

これにより、任意の位置の任意の文字列で番号3を検索できます


0

ジュリアでは、従うべきモデルを次のように説明できます。

using SQLite
using DataFrames

db = SQLite.DB("<name>.db")

register(db, SQLite.regexp, nargs=2, name="regexp")

SQLite.Query(db, "SELECT * FROM test WHERE name REGEXP '^h';") |> DataFrame

0

レール用

            db = ActiveRecord::Base.connection.raw_connection
            db.create_function('regexp', 2) do |func, pattern, expression|
              func.result = expression.to_s.match(Regexp.new(pattern.to_s, Regexp::IGNORECASE)) ? 1 : 0
            end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.