2015-06-01 11 views
0

我發現這個slugify功能在這裏:PHP function to make slug (URL string)如何將這個php slugify函數改寫爲mysql?

我試着將它改寫到MySQL,那就是我所做的就是:https://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/

  • 和音譯功能:

    ,但在輸出我只得到降低文本,沒有破折號和字母似乎也音譯,所以只剩下的東西是破折號。

    我的查詢:

    UPDATE `ad_kategorija` SET `slug_lt`=slugify(`kat_pavlt`), `slug_ru`=slugify(`kat_pavru`), `slug_en`=slugify(`kat_paven`) 
    

    功能:

    # Regex Replace function  
    DELIMITER $$ 
    
         CREATE DEFINER=`root`@`localhost` FUNCTION `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000)) RETURNS varchar(1000) CHARSET utf8 
          DETERMINISTIC 
         BEGIN 
         DECLARE temp VARCHAR(1000); 
         DECLARE ch VARCHAR(1); 
         DECLARE i INT; 
         SET i = 1; 
         SET temp = ''; 
         IF original REGEXP pattern THEN 
          loop_label: LOOP 
          IF i>CHAR_LENGTH(original) THEN 
          LEAVE loop_label; 
          END IF; 
          SET ch = SUBSTRING(original,i,1); 
          IF NOT ch REGEXP pattern THEN 
          SET temp = CONCAT(temp,ch); 
          ELSE 
          SET temp = CONCAT(temp,replacement); 
          END IF; 
          SET i=i+1; 
          END LOOP; 
         ELSE 
          SET temp = original; 
         END IF; 
         RETURN temp; 
         END$$ 
    
    # Transliteration function 
         CREATE DEFINER=`root`@`localhost` FUNCTION `transliterate`(original VARCHAR(512)) RETURNS varchar(512) CHARSET utf8 
         BEGIN 
    
          DECLARE translit VARCHAR(512) DEFAULT ''; 
          DECLARE len  INT(3)  DEFAULT 0; 
          DECLARE pos  INT(3)  DEFAULT 1; 
          DECLARE letter CHAR(1); 
          DECLARE is_lower BIT; 
    
          SET len = CHAR_LENGTH(original); 
    
          WHILE (pos <= len) DO 
          SET letter = SUBSTRING(original, pos, 1); 
          SET is_lower = IF(LCASE(letter) COLLATE utf8_bin = letter COLLATE utf8_bin, 1, 0); 
    
          CASE TRUE 
           WHEN letter = 'a' THEN SET letter = IF(is_lower, 'a', 'A'); 
           WHEN letter = 'b' THEN SET letter = IF(is_lower, 'b', 'B'); 
           WHEN letter = 'c' THEN SET letter = IF(is_lower, 'c', 'C'); 
           WHEN letter = 'd' THEN SET letter = IF(is_lower, 'd', 'D'); 
           WHEN letter = 'e' THEN SET letter = IF(is_lower, 'e', 'E'); 
           WHEN letter = 'f' THEN SET letter = IF(is_lower, 'f', 'F'); 
           WHEN letter = 'g' THEN SET letter = IF(is_lower, 'g', 'G'); 
           WHEN letter = 'h' THEN SET letter = IF(is_lower, 'h', 'H'); 
           WHEN letter = 'i' THEN SET letter = IF(is_lower, 'i', 'I'); 
           WHEN letter = 'j' THEN SET letter = IF(is_lower, 'j', 'J'); 
           WHEN letter = 'k' THEN SET letter = IF(is_lower, 'k', 'K'); 
           WHEN letter = 'l' THEN SET letter = IF(is_lower, 'l', 'L'); 
           WHEN letter = 'ł' THEN SET letter = IF(is_lower, 'l', 'L'); 
           WHEN letter = 'm' THEN SET letter = IF(is_lower, 'm', 'M'); 
           WHEN letter = 'n' THEN SET letter = IF(is_lower, 'n', 'N'); 
           WHEN letter = 'o' THEN SET letter = IF(is_lower, 'o', 'O'); 
           WHEN letter = 'p' THEN SET letter = IF(is_lower, 'p', 'P'); 
           WHEN letter = 'q' THEN SET letter = IF(is_lower, 'q', 'Q'); 
           WHEN letter = 'r' THEN SET letter = IF(is_lower, 'r', 'R'); 
           WHEN letter = 's' THEN SET letter = IF(is_lower, 's', 'S'); 
           WHEN letter = 't' THEN SET letter = IF(is_lower, 't', 'T'); 
           WHEN letter = 'u' THEN SET letter = IF(is_lower, 'u', 'U'); 
           WHEN letter = 'v' THEN SET letter = IF(is_lower, 'v', 'V'); 
           WHEN letter = 'w' THEN SET letter = IF(is_lower, 'w', 'W'); 
           WHEN letter = 'x' THEN SET letter = IF(is_lower, 'x', 'X'); 
           WHEN letter = 'y' THEN SET letter = IF(is_lower, 'y', 'Y'); 
           WHEN letter = 'z' THEN SET letter = IF(is_lower, 'z', 'Z'); 
           ELSE 
           SET letter = letter; 
          END CASE; 
    
          -- CONCAT seems to ignore the whitespace character. As a workaround we use 
          -- CONCAT_WS with a whitespace separator when the letter is a whitespace. 
          SET translit = CONCAT_WS(IF(letter = ' ', ' ', ''), translit, letter); 
          SET pos = pos + 1; 
          END WHILE; 
    
          RETURN translit; 
    
         END$$ 
    
    # slug create function 
         CREATE DEFINER=`root`@`localhost` FUNCTION `slugify`(`dirty_string` VARCHAR(255) CHARSET utf8) RETURNS varchar(255) CHARSET utf8 
          DETERMINISTIC 
         BEGIN 
          DECLARE temp_string VarChar(255) DEFAULT ''; 
          DECLARE output VarChar(255); 
    
          SET temp_string = regex_replace('~[^\\pL\\d]+~u', '-', dirty_string); 
    
          SET temp_string = TRIM(BOTH '-' FROM temp_string); 
    
          SET temp_string = transliterate(temp_string); 
    
          SET temp_string = LOWER(temp_string); 
    
          SET temp_string = regex_replace('~[^-\\w]+~', '', temp_string); 
    
          If temp_string = '' Then 
           SET temp_string = ''; 
          End If; 
    
          SET output = temp_string; 
    
          Return output; 
    
         END$$ 
    
         DELIMITER ; 
    

    所以有人可以幫我完成它,主要的問題是我沒有得到的空間替換了,也許正則表達式是錯誤的破折號。或者正則表達式替換函數需要一些插件來做到這一點。請幫忙。

  • +0

    出於好奇,你爲什麼要在MySQL中做到這一點? – Mjh

    +0

    @Mjh,所以我不需要編寫一個寫模塊,它將佔用10個表中的大塊,將其放入數組,然後將其轉換爲另一個非常需要資源的資源,然後將其放回到mysql中。我想這將是更容易宣佈這些功能,只是運行簡單的更新命令來重寫讓我們說的頁面標題slu。。所以你不需要手動改變每個頁面。或運行一些自定義的PHP數據庫更新程序腳本。希望這能滿足你的好奇心。它主要用於通過控制檯更改大規模數據庫。可以說,我的客戶決定在這個項目上獲得seo網址。解釋呢? – juslintek

    +0

    嗯,我很佩服你的奉獻精神,我會滿意PHP功能並通過它運行。即使在10萬條記錄中,它仍然能夠在一分鐘左右內完成。我只是想知道,因爲你花了相當一段時間在這方面,我通常太懶惰這樣的事情,喜歡更快的解決方案:) – Mjh

    回答

    0

    固定我的功能,去除regex_replace使用和替代使用功能從這裏開始:mySQL Stored Function to create a slug

    加音譯的調整,最終的代碼是在這裏。音譯功能不變:

    DELIMITER $$ 
    -- 
    -- Functions 
    -- 
    CREATE DEFINER=`root`@`localhost` FUNCTION `slugify`(`dirty_string` VARCHAR(255)) RETURNS varchar(255) CHARSET utf8 
        DETERMINISTIC 
    BEGIN 
        DECLARE x, y , z Int; 
        Declare temp_string, allowed_chars, new_string VarChar(255); 
        Declare is_allowed Bool; 
        Declare c, check_char VarChar(1); 
    
        set allowed_chars = "abcdefghijklmnopqrstuvwxyz-"; 
        set temp_string = transliterate(dirty_string); 
        set temp_string = lower(temp_string); 
    
        Select temp_string Regexp('&') Into x; 
        If x = 1 Then 
         Set temp_string = replace(temp_string, '&', ' and '); 
        End If; 
    
        Select temp_string Regexp('[^a-z0-9]+') into x; 
        If x = 1 then 
         set z = 1; 
         While z <= Char_length(temp_string) Do 
          Set c = Substring(temp_string, z, 1); 
          Set is_allowed = False; 
          Set y = 1; 
          Inner_Check: While y <= Char_length(allowed_chars) Do 
           If (strCmp(ascii(Substring(allowed_chars,y,1)), Ascii(c)) = 0) Then 
            Set is_allowed = True; 
            Leave Inner_Check; 
           End If; 
           Set y = y + 1; 
          End While; 
          If is_allowed = False Then 
           Set temp_string = Replace(temp_string, c, '-'); 
          End If; 
    
          set z = z + 1; 
         End While; 
        End If; 
    
        Select temp_string Regexp("^-|-$|'") into x; 
        If x = 1 Then 
         Set temp_string = Replace(temp_string, "'", ''); 
         Set z = Char_length(temp_string); 
         Set y = Char_length(temp_string); 
         Dash_check: While z > 1 Do 
          If Strcmp(SubString(temp_string, -1, 1), '-') = 0 Then 
           Set temp_string = Substring(temp_string,1, y-1); 
           Set y = y - 1; 
          Else 
           Leave Dash_check; 
          End If; 
          Set z = z - 1; 
         End While; 
        End If; 
    
        Repeat 
         Select temp_string Regexp("--") into x; 
         If x = 1 Then 
          Set temp_string = Replace(temp_string, "--", "-"); 
         End If; 
        Until x <> 1 End Repeat; 
    
        If LOCATE('-', temp_string) = 1 Then 
         Set temp_string = SUBSTRING(temp_string, 2); 
        End If; 
    
        Return temp_string; 
    END$$ 
    
    CREATE DEFINER=`root`@`localhost` FUNCTION `transliterate`(original VARCHAR(512)) RETURNS varchar(512) CHARSET utf8 
    BEGIN 
    
        DECLARE translit VARCHAR(512) DEFAULT ''; 
        DECLARE len  INT(3)  DEFAULT 0; 
        DECLARE pos  INT(3)  DEFAULT 1; 
        DECLARE letter CHAR(1); 
        DECLARE is_lower BIT; 
    
        SET len = CHAR_LENGTH(original); 
    
        WHILE (pos <= len) DO 
        SET letter = SUBSTRING(original, pos, 1); 
        SET is_lower = IF(LCASE(letter) COLLATE utf8_bin = letter COLLATE utf8_bin, 1, 0); 
    
        CASE TRUE 
         WHEN letter = 'a' THEN SET letter = IF(is_lower, 'a', 'A'); 
         WHEN letter = 'b' THEN SET letter = IF(is_lower, 'b', 'B'); 
         WHEN letter = 'c' THEN SET letter = IF(is_lower, 'c', 'C'); 
         WHEN letter = 'd' THEN SET letter = IF(is_lower, 'd', 'D'); 
         WHEN letter = 'e' THEN SET letter = IF(is_lower, 'e', 'E'); 
         WHEN letter = 'f' THEN SET letter = IF(is_lower, 'f', 'F'); 
         WHEN letter = 'g' THEN SET letter = IF(is_lower, 'g', 'G'); 
         WHEN letter = 'h' THEN SET letter = IF(is_lower, 'h', 'H'); 
         WHEN letter = 'i' THEN SET letter = IF(is_lower, 'i', 'I'); 
         WHEN letter = 'j' THEN SET letter = IF(is_lower, 'j', 'J'); 
         WHEN letter = 'k' THEN SET letter = IF(is_lower, 'k', 'K'); 
         WHEN letter = 'l' THEN SET letter = IF(is_lower, 'l', 'L'); 
         WHEN letter = 'ł' THEN SET letter = IF(is_lower, 'l', 'L'); 
         WHEN letter = 'm' THEN SET letter = IF(is_lower, 'm', 'M'); 
         WHEN letter = 'n' THEN SET letter = IF(is_lower, 'n', 'N'); 
         WHEN letter = 'o' THEN SET letter = IF(is_lower, 'o', 'O'); 
         WHEN letter = 'p' THEN SET letter = IF(is_lower, 'p', 'P'); 
         WHEN letter = 'q' THEN SET letter = IF(is_lower, 'q', 'Q'); 
         WHEN letter = 'r' THEN SET letter = IF(is_lower, 'r', 'R'); 
         WHEN letter = 's' THEN SET letter = IF(is_lower, 's', 'S'); 
         WHEN letter = 't' THEN SET letter = IF(is_lower, 't', 'T'); 
         WHEN letter = 'u' THEN SET letter = IF(is_lower, 'u', 'U'); 
         WHEN letter = 'v' THEN SET letter = IF(is_lower, 'v', 'V'); 
         WHEN letter = 'w' THEN SET letter = IF(is_lower, 'w', 'W'); 
         WHEN letter = 'x' THEN SET letter = IF(is_lower, 'x', 'X'); 
         WHEN letter = 'y' THEN SET letter = IF(is_lower, 'y', 'Y'); 
         WHEN letter = 'z' THEN SET letter = IF(is_lower, 'z', 'Z'); 
         ELSE 
         SET letter = letter; 
        END CASE; 
    
        -- CONCAT seems to ignore the whitespace character. As a workaround we use 
        -- CONCAT_WS with a whitespace separator when the letter is a whitespace. 
        SET translit = CONCAT_WS(IF(letter = ' ', ' ', ''), translit, letter); 
        SET pos = pos + 1; 
        END WHILE; 
    
        RETURN translit; 
    
    END$$ 
    
    DELIMITER ; 
    

    P.S.有人在聊天中詢問測試場景。您至少需要一張帶有2個varchars(255)列的表格。以及來自任何書籍或文本的句子,包含逗號,點號,括號,其他識別符號等。由於結果只有數字,單詞,字母和單個破折號必須保留。但是當我開始的時候,結果是空格的小寫字母。

    相關問題