วิธีใช้ SUBSTRING โดยใช้ REGEXP ใน MySQL


14

ฉันมีสถานการณ์ต่อไปนี้ ฉันต้อง substring นิพจน์ปกติจากคำอธิบายการใช้ MySQL รายละเอียด:

Lorem D9801 ipsum dolor sit amet

ตำแหน่งที่ D9801 คือ REGEXP คำอธิบายข้อความที่แข็งแกร่งทุกข้อความมีเนื้อหาที่แตกต่างกัน แต่ regexp ของฉันควรมีลักษณะดังนี้: REGEXP 'D [[::]]] {4}'

REGEXP มี "D" ที่จุดเริ่มต้นเสมอและ "xxxx" - 4 หลักที่ท้าย: Dxxxx

ฉันรู้ว่า REGEXP จะส่งกลับเฉพาะค่าจริง / เท็จ แต่ฉันจะสร้างคิวรีเพื่อส่งคืนเฉพาะค่า 'D9801' ได้อย่างไร

ฉันลองทำสิ่งนี้:

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

ฉันรู้ว่ามันผิดดังนั้นฉันลองทำสิ่งนี้:

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;

แต่จะหาตำแหน่งของ regexp ได้อย่างไร?

ฉันได้ยินเกี่ยวกับ UDF แต่ไม่สามารถใช้งานได้ฉันใช้ OVH โฮสติ้ง


โดยทั่วไปแล้วนี่เป็นคู่ของ: stackoverflow.com/questions/4021507/…
นาธานเฟกเกอร์

หากไม่มีการใช้ UDF จะไม่มีฟังก์ชันในตัวเพื่อดึงรูปแบบที่ตรงกันจากฟังก์ชัน REGEXP และวิธีการจับคู่อื่น ๆ ขึ้นอยู่กับการรู้จักสตริงทั้งหมดที่คุณกำลังจับคู่ซึ่งไม่สามารถใช้งานได้ในสถานการณ์นี้
Payload

คำตอบ:


3

สิ่งนี้จะต้องใช้LOCATEและSUBSTRINGไวยากรณ์เพื่อดึงข้อมูลออกมาจากสตริง พื้นฐานไวยากรณ์ค้นหาคุณจะต้องมีการอธิบายที่นี่

LOCATE (ค้นหา str, str, [ตำแหน่ง])

search str = สตริงที่จะค้นหา

str = สตริงที่จะถูกค้นหา

position (เป็นทางเลือก) = ตำแหน่งจากที่ (ภายในอาร์กิวเมนต์ที่สอง) การค้นหาจะเริ่มขึ้น

ในขณะที่ฟังก์ชั่นซับสตริงที่คุณต้องการอธิบายไว้ที่นี่

SUBSTRING (str, pos, len)

str = A สตริง

pos = ตำแหน่งเริ่มต้น

len = ความยาวเป็นตัวอักษร

วิธีที่ง่ายกว่าในการดูสิ่งนี้คือการคิดว่า substring เป็น SUBSTRING ต่อไปนี้ (str FROM pos for len)

ฉันใช้ไวยากรณ์เพื่อให้ได้คำที่สองอยู่ด้านล่างฉันใช้ประโยชน์จากช่องว่างที่อยู่รอบคำที่สองที่คุณพยายามแยกออกมาอย่างต่อเนื่อง

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

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

1

น่าเสียดายที่ฟังก์ชันนิพจน์ปกติของ MySQL คืนค่าเป็นจริงเท็จหรือเป็นโมฆะขึ้นอยู่กับว่านิพจน์นั้นมีอยู่หรือไม่

เคล็ดลับในการทำให้เกิดพฤติกรรมที่ต้องการคือการกำหนดว่าสตริงย่อยใดขึ้นต้นด้วยอักขระที่คุณสนใจมีความยาวที่ถูกต้องและตามด้วยตัวเลข ชุดของฟังก์ชัน substring_index ถูกใช้เพื่อแยกสตริง ...

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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.