最佳的创建/分割字符串为标签的方法

5
在我的php应用程序中,用户可以输入标签(就像在此处提问时一样)。 我假设它将是正则表达式,并且我使用了一个-mb_split('\W+', $text) - 通过非单词字符拆分。 但我想允许用户输入像“-,_,+,#”等字符,这些字符是有效的,并且通常出现在url中。 是否有现有的解决方案,或者可能是最佳实践? 谢谢。
8个回答

23
使用explode()函数,并通过空格或逗号进行分隔。示例:
$string = 'tag1 tag-2 tag#3';
$tags = explode(' ', $string); //Tags will be an array

用户输入“?”字符会导致 URL 错误。 - waney
不要忘记对任何用户输入进行urlencode()。这将防止'#'和'?'破坏URL。 - matpie

9

改为使用空格 \s+ 进行分割。


3

建议使用\s+(空格)进行分割,而不是\W+(非字母数字字符)。


2

您说您希望它的工作方式类似于stackoverflow标签器。此标记器通过空格字符“”将它们分割。

如果您也希望这是您的行为,只需使用:

mb_split('\s+', $text)

替代:

mb_split('\W+', $text)

祝你好运!


2

在将字符串分割为标签之前,您可以先尝试清理该字符串:

# List characters that you would want to exclude from your tags and clean the string
$exclude = array( '/[?&\/]/', '/\s+/');
$replacements = array('', ' '); 
$tags = preg_replace($exclude, $replacements,  $tags);

# Now split:
$tagsArray = explode(' ', $tags);

您可以采用白名单的方法来处理这个问题,将您接受的字符列在您的模式中。

1
我在我的应用程序中使用smart_explode()函数来解析标签:
function smart_explode ($exploder, $string, $sort = '') {
  if (trim ($string) != '') {
    $string = explode ($exploder, $string);
    foreach ($string as $i => $k) {
      $string[$i] = trim ($k);
      if ($k == '') unset ($string[$i]);
    }
    $u = array_unique ($string);
    if ('sort' == $sort) sort ($u);
    return $u;
  } else {
    return array ();
  }
}

它通过使用$exploder作为分隔符(通常是逗号)将$string分解为数组,删除重复项,修剪标记周围的空格,甚至在$sort为'sort'时为您排序标记。当$string为空时,它将返回一个空数组。

用法如下:

$mytaglist = smart_explode (',', '  PHP,  ,,regEx ,PHP');

以上将返回:

array ('PHP', 'regEx')

为了过滤掉你不喜欢的字符,请执行

 $mytaglist = str_replace (array ('?', '$', '%'), '_', $mytaglist);

在进行智能分解之前(列出数组中要替换为下划线的“坏”字符)。


1

处理标签的正确方法取决于您对输入处理的偏好:您可以完全删除无效的标签,也可以尝试清理标签使其变为有效。

在清理输入时应使用白名单方法来定义有效字符 - 黑名单中存在太多问题字符。

mb_internal_encoding('utf8');

$tags= 'to# do!"¤ fix-this str&ing';
$allowedLetters='\w';
// Note that the hyphen must be first or last in a character class pattern,
// to match hyphens, instead of specifying a character set range
$allowedSpecials='_+#-';

第一种方法是完全删除无效标签:

// The first way: Ignoring invalid tags

$tagArray = mb_split(' ', $tags);

$pattern = '^[' . $allowedLetters . $allowedSpecials . ']+$';

$validTags = array();
foreach($tagArray as $tag)
{
    $tag = trim($tag);
    $isValid = mb_ereg_match($pattern, $tag);
    if ($isValid)
        $validTags[] = $tag;
}

第二种方法尝试清除标签:
// The second way: Cleaning up the tag input

// Remove non-whitelisted characters
$pattern = '[^' . $allowedLetters . $allowedSpecials .']';

$cleanTags = mb_ereg_replace($pattern, ' ', $tags);

// Trim multiple white spaces.
$pattern = '\s+';
$cleanTags = mb_ereg_replace($pattern, ' ', $cleanTags);

$tags = mb_split(' ',$cleanTags);

用空格替换非法字符有时会导致问题 - 例如上面的 "str&ing" 被转换为 "str ing"。 完全删除非法字符将导致 "string",在某些情况下更有用。


0
使用 preg_match_all
$tags = array();
if(preg_match_all('/\s*(.*)\s*/U',$tags)) unset($tags[0]);
//now in $tags you have an array of tags. 

如果标签是UTF-8编码,那么在正则表达式中添加u修饰符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接