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

이것을 시도 할 때 오류가 발생하는 사람들을 위해 아래 응답을 확인하십시오. stackoverflow.com/a/18484596/1585572 코드를 파일에 넣고 Firefox sqlite 관리자의 사용자 정의 함수로 가져 왔습니다. 하지만 다음과 같이 약간 다르게 호출해야합니다. 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 || ','
바룩

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또는 $pattern단지 MySQL은 같은 - NULL이며, 그 결과는 NULL이다.


8

sqlite3을 사용하는 파이썬의 내 솔루션 :

   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

거의 1 년 전에 게시 된 질문에 답하는 것은 좋지 않습니다. 하지만 Sqlite 자체가 REGEXP 기능을 제공한다고 생각하는 사람들을 위해이 글을 쓰고 있습니다. .

sqlite에서 REGEXP 함수를 호출하기위한 기본 요구 사항 중 하나는
"응용 프로그램에서 고유 한 함수를 만든 다음 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

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


IMHO 검사는 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

당신은 또한 고려할 수 있습니다

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

이렇게하면 모든 위치의 모든 문자열에서 3 번을 찾을 수 있습니다.


0

Julia에서 따라야 할 모델은 다음과 같이 설명 할 수 있습니다.

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.