Cara menggunakan SUBSTRING menggunakan REGEXP di MySQL


14

Saya memiliki situasi berikut. Saya harus mengurangi ekspresi reguler dari deskripsi menggunakan MySQL. Deskripsi:

Lorem D9801 ipsum dolor sit amet

Di mana D9801 adalah REGEXP. Setiap deskripsi teks yang kuat memiliki konten yang berbeda tetapi regexp saya akan terlihat seperti: REGEXP 'D [[: digit:]] {4}'

REGEXP selalu memiliki "D" di awal dan "xxxx" - 4 digit di akhir: Dxxxx

Saya tahu REGEXP hanya mengembalikan nilai true / false, tetapi bagaimana saya bisa membuat kueri untuk mengembalikan hanya nilai 'D9801'?

Saya mencoba sesuatu seperti ini:

SELECT SUBSTRING (description, LOCATE(REGEXP 'D[[:digit:]]{4}', description), 5)
FROM (
   SELECT "Lorem D9801 ipsum dolor sit amet" AS description
) temp

Saya tahu itu salah, jadi saya coba dengan ini:

SELECT 
    id, 
    SUM(description REGEXP 'D[[:digit:]]{4}') AS matches, 
    CASE
        WHEN (SUM(description REGEXP 'D[[:digit:]]{4}') > 0) THEN 
            SUBSTRING(description, LOCATE( /*POSITION_OF_REGEXP_IN_DESC*/ , description), 5)
        ELSE 'Brak schematu'
    END AS show_substr FROM ps_description GROUP BY id;

Tetapi bagaimana cara menemukan posisi regexp?

Saya mendengar tentang UDF tetapi saya tidak dapat menggunakannya, saya menggunakan hosting OVH.


Ini pada dasarnya adalah dup dari: stackoverflow.com/questions/4021507/…
Nathan Feger

Tanpa menggunakan UDF, tidak ada fungsionalitas bawaan untuk mengambil pola yang cocok dari fungsi REGEXP dan metode pencocokan lainnya bergantung pada mengetahui string lengkap yang cocok untuk Anda yang tidak berfungsi dalam situasi ini
Payload

Jawaban:


3

Ini perlu menggunakan LOCATEdan SUBSTRINGsintaks untuk mendapatkan informasi dari string. Sintaksis lokasi dasar yang Anda perlukan dijelaskan di sini .

LOCATE (str pencarian, str, [posisi])

search str = Sebuah string yang akan dicari.

str = Sebuah string yang akan dicari.

position (opsional) = Posisi dari mana (dalam argumen kedua) pencarian akan dimulai.

Sementara fungsi substring yang Anda butuhkan dijelaskan di sini

SUBSTRING (str, pos, len)

str = A string.

pos = Posisi awal.

len = Panjang karakter.

Cara yang lebih mudah untuk melihatnya adalah dengan menganggap substring sebagai SUBSTRING berikut (str FROM pos FOR len)

Sytax yang saya gunakan untuk mendapatkan kata kedua di bawah ini, saya mengambil keuntungan dari spasi yang terus-menerus di sekitar kata kedua yang Anda coba untuk mengekstrak.

declare @String varchar(50) ='Lorem D9801 ipsum dolor sit amet'

SUBSTRING
(
@String,
LOCATE(' ', @String),
LOCATE(' ', @String, (LOCATE(' ', @String) + 1)) - LOCATE(' ', @String)
)

1

Sayangnya, fungsi ekspresi reguler MySQL mengembalikan true, false, atau null tergantung apakah ekspresi itu ada atau tidak.

Trik dalam mempengaruhi perilaku yang diinginkan adalah untuk menentukan substring yang dimulai dengan karakter yang Anda pedulikan, memiliki panjang yang benar, dan diikuti oleh angka. Serangkaian fungsi substring_index digunakan untuk mengekstrak string ...

set @string:='Lorem D9801 ipsum dolor sit amet';
select
case when @string like '% D____ %' and cast((@num:= substring_index(substring_index(@string,concat(substring_index(@string,' D',1),' D'),-1),' ',1)) as signed) between '0' and '9999' then concat('D',@num)
     when @string like '% D% D____ %' and cast((@num:= substring_index(substring_index(@string,concat(substring_index(@string,' D',2),' D'),-1),' ',1)) as signed) between '0' and '9999' then concat('D',@num)
     when @string like '% D% D% D____ %' and cast((@num:= substring_index(substring_index(@string,concat(substring_index(@string,' D',3),' D'),-1),' ',1)) as signed) between '0' and '9999' then concat('D',@num)
     when @string like '% D% D% D% D____ %' and cast((@num:= substring_index(substring_index(@string,concat(substring_index(@string,' D',4),' D'),-1),' ',1)) as signed) between '0' and '9999' then concat('D',@num)
     when @string like '% D% D% D% D% D____ %' and cast((@num:= substring_index(substring_index(@string,concat(substring_index(@string,' D',5),' D'),-1),' ',1)) as signed) between '0' and '9999' then concat('D',@num)
end as test_case;
+-----------+
| test_case |
+-----------+
| D9801     |
+-----------+
1 row in set (0.00 sec)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.