2016-04-04 2 views
2

У меня есть документ, полный шестигранных цветов, как показано ниже.Переупорядочение строк в PHP

#123 is a nice colour but #321 is also fine. However, #fe4918 isn't a bad either. 

Я хотел бы, чтобы повернуть их вокруг, так что #123 станет #231, эффективно изменяя цветовую схему. #fe4918 будет #4918fe.

Я знаю, что с регулярными выражениями можно выбрать теги хеша, но не намного больше.

+0

А как насчет '# fe4918'? –

+0

@ karthikmanchala, извинения. Там мы идем! – Lolums

ответ

3

Вы можете использовать регулярные выражения, чтобы сделать это ...

preg_replace('/#([\da-f])([\da-f])([\da-f])(?:([\da-f])([\da-f])([\da-f]))?/i', '#$2$5$3$6$1$4', $str) 

CodePad

Он работает путем сопоставления нечувствительны к регистру шестнадцатеричным числам 3 или 6 раз, а затем переворачивает их с помощью совпавших групп.

В качестве альтернативы вы можете сравнить его с простым регулярным выражением и обратным вызовом с помощью preg_replace_callback() и использовать strrev(), но я думаю, что приведенный выше пример достаточно ясен.

+0

Это сработало для меня, хотя я изменил порядок номеров на замену. Благодаря! – Lolums

+0

@Lolums Извините, я пропустил эту деталь. Рад, что он работает на вас. – alex

+0

Да, порядок замены неверен. Должно быть '' '# $ 2 $ 5 $ 3 $ 6 $ 1 $ 4'''. – docksteaderluke

1

Вы можете использовать комбинацию регулярных выражений и strrev():

#([a-f0-9]+) 

В PHP это было бы:

<?php 
$string = "#123 is a nice colour but #321 is also fine. However, #fe4918 isn't a bad either."; 
$regex = '~#([a-f0-9]+)~'; 

$string = preg_replace_callback(
    $regex, 
    function($match) { 
     return '#'.strrev($match[1]); 
    }, 
    $string 
); 
echo $string; 
// #321 is a nice colour but #123 is also fine. However, #8194ef isn't a bad either. 
?> 

Вы можете сделать это в регулярном выражении в одиночку, но выше логика кажется очень ясный (и поддерживаемый в течение нескольких месяцев).
См. Демонстрационную версию на ideone.com.

1

Вы можете использовать следующее соответствие:

#([\da-f]{2})([\da-f]{2})([\da-f]{2})|#(\d)(\d)(\d) 

И заменить:

#\2\5\3\4\1\6 

См RegEX DEMO

1

Вы можете использовать группу сброса ветви обрабатывать два случая с такие же номера группы захвата:

$str = preg_replace('~#(?|([a-f\d]{2})([a-f\d]{4})|([a-f\d])([a-f\d]{2}))~i', 
        '#$2$1', $str); 
Смежные вопросы