亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將包含重復 n 次的相同子字符串的字符串減少為子字符串的單個實例

如何將包含重復 n 次的相同子字符串的字符串減少為子字符串的單個實例

PHP
慕斯709654 2023-04-21 17:44:03
'ageage'我有像or'feetfeetfeet'或這樣的字符串'cmcmcmcmcm',我想分別將它們減少為'age', 'feet', 和'cm'。這是規范化的中間步驟,用于匹配最初也包含數字的某些類別的數據字段的不同數據源。數字部分已被刪除到一個單獨的字符串中。所有的 unicode 字母都被音譯為小寫 ASCII 字母:public static function transliterate(string $value){    $transliterator = Transliterator::createFromRules(        ':: Any-Latin; :: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: Lower(); :: NFC;',        Transliterator::FORWARD    );    return $transliterator->transliterate($value);}另請注意,復數并不重要,因為雖然我提供的示例是英文的,但該項目主要規范化土耳其語字符串,其中此類單詞始終是單數。我希望這可以用正則表達式來完成。雖然我不完全確定如何
查看完整描述

4 回答

?
小怪獸愛吃肉

TA貢獻1852條經驗 獲得超1個贊

我認為非正則表達式沒問題。


此方法遍歷一半的字符串并嘗試查找如果在 str_replace 中使用則不返回任何內容的子字符串。

如果我們發現了,那么我們就知道這是一個重復的詞。


$str = 'feetfeetfeet';

$return = $str; // return full str if it fails


$len = strlen($str);


for($i = 1; $i < $len/2; $i++){

    $sub = substr($str, 0, $i);

    if(str_replace($sub, "", $str) == ""){

        $return = $sub;

        break;

    }

}


echo $return; //feet


查看完整回答
反對 回復 2023-04-21
?
大話西游666

TA貢獻1817條經驗 獲得超14個贊

  • 這看起來類似于查找也是后綴的最長公共前綴?,F在,這length - longest prefix which is also a suffix就是您的答案。你可以從這個找到構建前綴后綴表的算法KMP pattern matching algorithm

  • 時間復雜度為O(n),空間復雜度為O(n)。

片段:

<?php


$str = "feetfeetfeet";

$length = strlen($str);


$prefix_suffix_table = array_fill(0, $length, 0);


$j = 0;

for($i = 1; $i < $length; ++$i){

? ? while($j > 0 && $str[$i] != $str[$j]){

? ? ? ? $j = $prefix_suffix_table[$j - 1];

? ? }


? ? if($str[$i] == $str[$j]){

? ? ? ? $prefix_suffix_table[$i] = ++$j;

? ? }

}


echo substr($str, 0, $length - end($prefix_suffix_table));

注意:如果您的字符串格式不正確,例如xyz沒有重復的子字符串,您可以使用添加額外的檢查str_repeat()并在需要時拋出異常。


查看完整回答
反對 回復 2023-04-21
?
MMMHUHU

TA貢獻1834條經驗 獲得超8個贊

我已經想出如何使用正則表達式來做到這一點。盡管我已經意識到它可能對我的目的沒有用,因為 mmmm 可以是 2x mm(毫米)或 4x m(米)。雖然如果我只關心最多支持 3 次重復,我可以使用:


if(preg_match('/^([a-z]*)\1{2}$/', $input, $matches)) {

    $repeating = $matches[1];

    $reps = 3;

} elseif(if(preg_match('/^([a-z]*)\1$/', $input, $matches)) {

    $repeating = $matches[1];

    $reps = 2;

} else {

    $repeating = $input;

    $reps = 1;

}

并不是說下面會把字符串分成最小的重復素數:


preg_match('/^([a-z]*)\1+$/', $input, $matches);

$repeating = $matches[1];

這是此輸出的表格:


┌────────────┬────────────┐

│   $input   │ $repeating │

├────────────┼────────────┤

│ mm         │ m          │

│ mmm        │ m          │

│ mmmm       │ mm         │

│ mmmmm      │ m          │

│ mmmmmm     │ mmm        │

│ mmmmmmm    │ m          │

│ mmmmmmmm   │ mmmm       │

│ mmmmmmmmm  │ mmm        │

│ mmmmmmmmmm │ mmmmm      │

└────────────┴────────────┘

因為只考慮最小的素數細分


preg_match('/^([a-z]*)\1{1,2}$/', $input, $matches)

不合適,因為它會像上表一樣,發現 'mmmmmm' 的重復部分是 'mmm' 而不是所需的 mm。


我在開頭提供的三個案例實施是我目前正在使用的,因為我的輸入通常是產品的年齡組或維度,我還沒有看到產品被描述為超過三個維度或年齡組,'11yr,12yr,13yr,14yr'雖然我可以想象像后者這樣的事情,無論多么罕見,最終都會發生。因此,我可能會放棄這種方法,轉而使用 preg_match_all 從包含數字的原始字符串中提取單位:


preg_match_all('/([0-9]+)\s*([a-z]*)\s*/', $input, $matches)

然而,如果其他人實際上有興趣找到最小的重復子字符串(所以 'm' 代表 'mmmm'),這可以通過循環中的正則表達式來完成:


$repeating = $input;

while(preg_match('/^([a-z]*)\1+$/', $repeating, $matches)) {

    $repeating = $matches[1];

}

這將產生:


┌────────────┬────────────┐

│   $input   │ $repeating │

├────────────┼────────────┤

│ mm         │ m          │

│ mmm        │ m          │

│ mmmm       │ m          │

│ mmmmm      │ m          │

│ mmmmmm     │ m          │

│ mmmmmmm    │ m          │

│ mmmmmmmm   │ m          │

│ mmmmmmmmm  │ m          │

│ mmmmmmmmmm │ m          │

│ cmcm       │ cm         │

│ cmcmcm     │ cm         │

│ cmcmcmcm   │ cm         │

│ cmcmcmcmcm │ cm         │

└────────────┴────────────┘


查看完整回答
反對 回復 2023-04-21
?
搖曳的薔薇

TA貢獻1793條經驗 獲得超6個贊

您還可以使用str_split()將字符串轉換為數組并找到其唯一元素,然后再次返回將所有唯一元素內爆在一起。


<?php

$str = array_unique(str_split('ageage'));

$result = implode($str);

?>

輸出


age


查看完整回答
反對 回復 2023-04-21
  • 4 回答
  • 0 關注
  • 162 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號