Преобразование строки, но оставление символов в скобках - PullRequest
0 голосов
/ 17 октября 2018
  1. Я конвертирую строку ввода пользователя (успешно, но ...)
  2. Я хотел бы игнорировать символы, заключенные в фигурные скобки
  3. Также удалите фигурные скобки в окончательном выводе

Так, например, если у меня есть эта строка:

$string = "[ABC] This & Text";

function make_post_type($string) {
  $needle   = array('-', ' ');
  $clean    = preg_replace("/[^a-zA-Z0-9_\s]/", "", strtolower($string)); // Remove special characters
  $haystack = preg_replace('!\s+!', ' ', $clean); // Now remove extra spaces

  return str_replace($needle, '_', $haystack);
}

возвращает abc_this_text

Я хотел бы вернуть ABC_this_text

Ответы [ 4 ]

0 голосов
/ 18 октября 2018

Вы можете уменьшить количество шагов для создания желаемой строки, посмотрев на проблему по-другому.Сначала сопоставьте то, что вам нужно, затем замените пробелы и тире на _ в конце:

function make_post_type($s) {
    preg_match_all("~({[^{}]*}|\[[^][]*])|[\w\s]+~", $s, $m);
    $s = '';
    foreach($m[0] as $k => $v) {
        $s .= $m[1][$k] ? substr($v, 1, -1) : strtolower($v);
    }
    return preg_replace('~[-\s]+~', '_', $s);
}

Я заключил {[^{}]*}|\[[^][]*] в скобки, чтобы позже можно было проверить (bool) $m[1][$k], который сообщает, является ли текущее значение витерация существует в захваченных группах, возвращаемых $m[1], затем удаляет один начальный и конечный символ из строки.

См. живое демо здесь

0 голосов
/ 17 октября 2018

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

function replc($str) {
   return preg_replace_callback (
      '/\[([^]]*)\]|{([^}]*)}|([^][{}]+)/',
      function ($m) {
         return (isset($m[1])?$m[1]:"") .
                (isset($m[2])?$m[2]:"") .
                 (isset($m[3]) ?
                 preg_replace('/\W+/', '_', strtolower($m[3])) : "");
      },
      $str
   );
}

Назовите его как:

echo replc( "[ABC] This & Text" );
ABC_this_text

echo replc( "abc.Xyz {PQR} Foo-Bar [ABC] This & Text" );
abc_xyz_PQR_foo_bar_ABC_this_text

1-й Регламент Подробнее:

  • [([^]]*)\]: если мы встретим [...], захватить внутреннюю часть в группе # 1
  • |: ИЛИ
  • {([^}]*)}:Если мы встретим {...}, то захватим внутреннюю часть в группе # 2
  • |: ИЛИ
  • [^][{}]+: совпадение с 1+ символом, который не является [ и ] и{ и } и захват в группе № 3

2-е RegEx:

  • \W+: совпадение 1+ не-словосимвол, подлежащий замене на _
0 голосов
/ 17 октября 2018

Вы можете использовать preg_match_all и использовать 2 группы захвата.

\[([A-Z]+)\]|(\w+)

Используйте array_reduce , чтобы проверить группы захвата по индексу и, наконец, взорваться, используя подчеркивание:

Например:

$re = '/\[([A-Z]+)\]|(\w+)/';
$string = "[ABC] This & Text";
preg_match_all($re, $string, $matches, PREG_SET_ORDER, 0);

echo implode('_', array_reduce($matches, function($carry, $item){
    if ($item[1] === "") {
        $carry[] = strtolower($item[2]);
        return $carry;
    }
    $carry[] = $item[1];
    return $carry;

})); //ABC_this_text

Пояснение

  • \[([A-Z]+)\] Совпадение [, захват 1+ заглавных букв в группе и совпадение ].Чтобы сопоставить все в скобках, вместо этого можно использовать \[([^]]+)\].
  • | или
  • (\w+) Захватывать в группе 1+ слов символов.Если вы хотите сопоставить больше, чем \w, вы можете использовать класс символов и добавить то, что хотите сопоставить, например, [\w!?]+

Regex demo | Php demo

0 голосов
/ 17 октября 2018

Одно из решений состоит в том, чтобы разбить строку на массив слов.
Если слово содержит [], удалить только их, в противном случае выполните все остальные операции со специальными символами и strtolower.

Затемвзорваться обратно в строку и вернуть

$string = "[ABC] This & Text";
Echo make_post_type($string);


function make_post_type($string) {
  $needle   = array('-', ' ');
  $arr = explode(" ", $string);
  foreach($arr as &$a){
     if($a[0] != "[" && $a[-1] != "]"){
        $a = preg_replace("/[^a-zA-Z0-9_\s]/", "", strtolower($a)); // Remove special characters
     }else{
        $a = substr($a, 1,-1);
     }
  }
  $string = preg_replace('!\s+!', ' ', implode(" ", $arr)); // Now remove extra spaces

  return str_replace($needle, '_', $string);
}

https://3v4l.org/rZlaP

...