Bir SQLite sorgusunda regex'i nasıl kullanırım?


105

Sqlite'de normal bir ifade kullanmak istiyorum ama nasıl yapılacağını bilmiyorum.

Tablomda şöyle dizeleri olan bir sütun var: "3,12,13,14,19,28,32" Şimdi "x GİBİ '3'" yazarsam 13 veya 32 gibi değerler içeren satırları da alırım , ancak yalnızca bu dizede tam olarak 3 değerine sahip satırları almak istiyorum.

Bunun nasıl çözüleceğini bilen biri var mı?


Yanıtlar:


74

SQLite3, REGEXP operatörünü destekler:

WHERE x REGEXP <regex>

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


3
Kolay bir yol buldum: Basitçe \ bx \ b burada x dizede
aranacak

12
@DanS: Operatörü regex()desteklemek için nasıl bir işlev eklersiniz REGEXP? Varsayılan olarak bir kullanıcı işlevi eklenmemiştir.
SK9

48
Sqlite belgelerine göre: REGEXP operatörü, regexp () kullanıcı işlevi için özel bir sözdizimidir. Varsayılan olarak hiçbir regexp () kullanıcı işlevi tanımlanmamıştır ve bu nedenle REGEXP işlecinin kullanılması normalde bir hata mesajıyla sonuçlanır. Çalışma zamanında "regexp" adlı uygulama tanımlı bir SQL işlevi eklenirse, REGEXP işlecini uygulamak için bu işlev çağrılır. ( sqlite.org/lang_expr.html#regexp )
radicand

Bunu denediğinizde hata alanlarımız için stackoverflow.com/a/18484596/1585572 aşağıdaki yanıtı kontrol edin Kodu bir dosyaya koydum ve Firefox sqlite yöneticimdeki Kullanıcı Tanımlı İşlevlere aktardım. Yine de, biraz farklı bir şekilde çağırmanız gerekir, şöyle: SELECT * FROM table WHERE column regexp ("myregexp")
Tristan

Bu nasıl kabul edilen bir cevap? Lütfen stackoverflow.com/a/8338515/828885 altındaki mivk'in daha yüksek puan alan yanıtına bakın .
akhan

114

Başkalarının daha önce de belirttiği gibi, REGEXP, önce tanımlanması ve veritabanına yüklenmesi gereken kullanıcı tanımlı bir işlevi çağırır. Belki bazı sqlite dağıtımları veya GUI araçları bunu varsayılan olarak içerir, ancak benim Ubuntu kurulumum bunu yapmadı. Çözüm oldu

sudo apt-get install sqlite3-pcre

Perl düzenli ifadelerini yüklenebilir bir modülde uygulayan /usr/lib/sqlite3/pcre.so

Kullanabilmek için, veritabanını her açtığınızda yüklemeniz gerekir:

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

Ya da bu satırı kendi sayfanıza koyabilirsiniz ~/.sqliterc.

Şimdi şu şekilde sorgulayabilirsiniz:

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

Doğrudan komut satırından sorgulamak istiyorsanız -cmd, kütüphaneyi SQL'inizden önce yüklemek için anahtarı kullanabilirsiniz :

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

Windows kullanıyorsanız, sanırım benzer bir .dll dosyası bir yerde bulunmalıdır.


15
Başka bir yükleme seçeneği: Bununla bir görünüm oluşturdum: SELECT load_extension ('/ usr / lib / sqlite3 / pcre.so'); Bu şekilde, DB için GUI tabanlı bir giriş noktası kullandığımda (Firefox'taki SQLite Manager gibi), REGEXP özelliğini yüklemek için bir yolum var.
Paulb

30

Bunu normal ifade olmadan çözmenin karmaşık bir yolu where ',' || x || ',' like '%,3,%'


1
Evet ben öyle düşünmüştüm ama her seferinde "" liderlik etme veya takip etme "yok. Yine de teşekkürler :-)
cody

Buradaki soruna rastlamadım - bu x sütun adı olarak işe
yarayıp yaramayacağını

3
Kullanmalısınız',' || x || ','
Baruch

22

SQLite, varsayılan olarak normal ifade işlevselliği içermez.

Bir REGEXPişleci tanımlar , ancak siz veya çerçeveniz adlı bir kullanıcı işlevi tanımlamadıkça bu bir hata mesajıyla başarısız olur regexp(). Bunu nasıl yapacağınız, platformunuza bağlı olacaktır.

regexp()Tanımlanmış bir işleviniz varsa, aşağıdaki gibi virgülle ayrılmış bir listeden rastgele bir tamsayıyı eşleştirebilirsiniz:

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

Ancak, tek bir sütundaki bu grupları virgülle ayrılmış listedeki her numara için ayrı bir satırla değiştirerek veritabanı yapınızı normalleştirdiyseniz, işleri çok daha kolay bulacağınız görülüyor. O zaman normal bir ifade yerine yalnızca operatörü kullanmakla kalmaz, aynı zamanda SQL'in size sağladığı birleştirmeler gibi daha güçlü ilişkisel araçları da kullanabilirsiniz.=


14

MySQL'deki REGEXPdavranışı taklit eden anahtar kelime için PHP / PDO'da bir SQLite UDF'si :

$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;
    }
);

Değiştirici uMySQL'de uygulanmıyor, ancak varsayılan olarak sahip olmayı yararlı buluyorum. Örnekler:

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

Eğer ikisinden biri $dataveya $patternsadece MySQL gibi - NULL'dur, sonuç geçersiz olacaktır.


9

Python'daki çözümüm sqlite3 ile:

   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()

normal ifade eşleşirse, çıktı 1 olur, aksi takdirde 0 olur.


5

Neredeyse bir yıl önce yayınlanan bir soruyu cevaplamak iyi değil. Ama SQLite kendisi işlevi sağladığını düşünenler için yazıyorum RegExp .

Sqlite'da REGEXP işlevini çağırmak için temel bir gereksinim,
"Uygulamada kendi işlevinizi oluşturmalı ve ardından sqlite sürücüsüne geri arama bağlantısını sağlamalısınız" .
Bunun için sqlite_create_function (C arayüzü) kullanmanız gerekir. Detaylara buradan ve buradan ulaşabilirsiniz


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

Ve :

SELECT * from TableName
 WHERE YourField REGEXP 'YOUR REGEX'

4

Kapsamlı veya'ed where cümlesi bunu dize birleştirme olmadan yapabilir:

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

Dört vaka tam eşleme, liste sonu, liste başı ve orta liste içerir.

Bu daha ayrıntılıdır, normal ifade uzantısını gerektirmez.


4

Python ile, conSQLite bağlantısı olduğunu varsayarsak , gerekli UDF'yi şunu yazarak tanımlayabilirsiniz:

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

İşte daha eksiksiz bir örnek:

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' ")


IMHO çek if x not Null and y not Null and re.search(x,y)aksi takdirde fırlatacaktır.
pholat

2

REGEXP ile normal ifade kullanabilirsiniz , ancak bu tam eşleşme yapmanın aptalca bir yoludur.

Sadece söylemelisin WHERE x = '3'.


Bunu daha iyi açıklamalıydım (zayıf ingilizcem için özür dilerim), sadece belirli bir kesin değeri kastetmiştim, tam dizeyi değil. Yine de teşekkürler!
cody

2

Bunu kullanmayı düşünün

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

X içeride olduğunda bu tam olarak 3 ile eşleşecek:

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

Diğer örnekler:

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

Bu 3 veya 13'te eşleşecek


1

Android Sqlite için normal ifade dışı koşulu arayan birinin bu dize gibi olması durumunda, @phyatt koşulunda parantez ( {} ) gibi diğer özel karakterler için aynı [1,2,3,4,5]köşeli parantez ( [] ) eklemeyi unutmayın.

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


0

Ayrıca düşünebilirsiniz

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

Bu, herhangi bir konumda herhangi bir dizede 3 numarayı bulmaya izin verecektir


0

Julia'da izlenecek model şu şekilde gösterilebilir:

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

raylar için

            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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.