Сопоставить и заменить строку с помощью REGEX в Sqlite? - PullRequest
2 голосов
/ 20 января 2020

У меня есть таблица personal_websessions, которая содержит данные в следующем формате:

 id_no | website_link 
 1     | google.com 
 2     | stackoverflow.com 
 3     | msn.com 

Вы можете создать эту таблицу, используя следующие команды SQL:

CREATE TABLE personal_websessions(id_no INTEGER PRIMARY KEY, website_link TEXT);
INSERT INTO personal_websessions VALUES(1, 'google.com'), (2, 'stackoverflow.com '), (3, 'msn.com ')

Я бы хотел бы выполнить поиск и замену с помощью регулярных выражений :

Что бы я хотел сделать, это если бы символ был 'msn.com' или 'msnnews.com et c (что-то с msn в слове) в столбце website_link найдите это значение «msn» и замените его строкой «toast», но если оно не является словом msn , тогда оставьте это как есть. поэтому приведенный выше пример - google.com и stackoverflow.com останутся прежними.

Я знаю, что регулярное выражение будет иметь форму (msn) в виде структуры группировки для сопоставления, но я не знаю, как написать соответствие регулярному выражению в Sqlite.

По сути, у меня будет следующий желаемый вывод ниже:

 id_no | website_link 
 1     | google.com 
 2     | stackoverflow.com 
 3     | toast

В настоящее время я использую SQlite и знаю, что мне придется использовать функцию REPLACE, так как она может найти шаблон и затем предоставить замену,

Однако в этой ссылке они не используют регулярные выражения для сопоставления слов, просто определяя их

На самом деле я просто пытаюсь выяснить, как использовать шаблон регулярных выражений для поиска и заменить значения в sqllite.

Я использую соединение RSQLITE, если это поможет.

Спасибо

Ответы [ 2 ]

2 голосов
/ 20 января 2020

То, что вы описываете, например, фильтрацию звуков с использованием like:

update personal_websessions
    set website_link = 'toast'
    where website_link like 'msn%';

В ваших примерах "msn" находится в начале, поэтому я расположил подобный шаблон, чтобы соответствовать этому. Если вы действительно где-то имеете в виду «msn», то шаблон должен быть '%msn%'.

Функция replace() действительно не имеет ничего общего с этой проблемой. Если вы хотите изменить базовые данные, тогда update - это оперативная команда.

РЕДАКТИРОВАТЬ:

Если вы не хотите изменять данные, а просто хотите select, затем используйте выражение case:

select pw.id_no,
       (case when pw.website_link like 'msn%' 
             then 'toast'
             else pw.website_link
        end) as website_link
from personal_websessions pw;
0 голосов
/ 27 января 2020

Вы можете использовать функцию SQLite regexp, но только после ее регистрации.

con0 <- DBI::dbConnect(RSQLite::SQLite())
DBI::dbExecute(con0, "CREATE TABLE personal_websessions(id_no INTEGER PRIMARY KEY, website_link TEXT)")
# [1] 0
DBI::dbExecute(con0, "INSERT INTO personal_websessions VALUES(1, 'google.com'), (2, 'stackoverflow.com '), (3, 'msn.com ')")
# [1] 3
DBI::dbExecute(con0, "INSERT INTO personal_websessions VALUES(4, 'msnnews.com')")
# [1] 1
DBI::dbGetQuery(con0, "select * from personal_websessions where website_link like 'msn%'")
#   id_no website_link
# 1     3     msn.com 
# 2     4  msnnews.com
DBI::dbGetQuery(con0, "select * from personal_websessions where website_link regexp '\\bmsn\\b'")
# Error: no such function: regexp
RSQLite::initRegExp(con0)
DBI::dbGetQuery(con0, "select * from personal_websessions where website_link regexp '\\bmsn\\b'")
#   id_no website_link
# 1     3     msn.com 

Чтобы заменить"msn" на "toast" (внутри строки (в качестве замены подстроки), однако, SQLite в настоящее время не имеет встроенной поддержки замены регулярного выражения (за исключением icu_replace.c, найдено здесь ).

Если вы уверены, что вы будете не найти "msn" несколько раз в одной строке (например, "msnnews.msn.com"), однако вы можете найти с помощью регулярного выражения (как указано выше) и затем использовать не регулярное выражение replace. Продолжая приведенный выше пример:

DBI::dbGetQuery(con0, "
  select id_no, replace(website_link,'msn','toast') as website_link
  from personal_websessions
  where website_link regexp '\\bmsn\\b'")
#   id_no website_link
# 1     3   toast.com 

И если вам нужно заменить все строки только этой частью, объединение будет работать:

DBI::dbGetQuery(con0, "
  select id_no, replace(website_link,'msn','toast') as website_link
  from personal_websessions
  where website_link regexp '\\bmsn\\b'
  union
  select id_no, website_link
  from personal_websessions
  where not website_link regexp '\\bmsn\\b' ")
#   id_no       website_link
# 1     1         google.com
# 2     2 stackoverflow.com 
# 3     3         toast.com 
# 4     4        msnnews.com
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...