簡體   English   中英

正則表達式刪除除表情符號以外的所有非字母數字字符

[英]regex remove all non alphanumeric characters except emoticons

我需要刪除除空格和允許表情符號之外的所有非字母數字字符。

允許的表情符號是:):( :P等(最受歡迎)。

我有一個字符串:

$string = 'Hi! Glad # to _ see : you :)';

所以我需要處理這個字符串並獲得以下內容:

$string = 'Hi Glad to see  you :)';

另外請注意表情符號可以包含空格

例如

而不是:)):

要么

:P代替:P

有人有這個功能嗎?

如果有人幫助過我會很棒:)

UPDATE

非常感謝您的幫助。

巴克利提供現成的解決方案

但如果字符串包含帶空格的表情符號

嗨! 很高興見到你 : )

結果等於嗨很高興見到你

正如你看到的表情:)被切斷。

我不“說”php;)但這是在JS中做到的。 也許你可以轉換它。

var sIn = 'Hi! Glad # to _ see : you :)',
    sOut;

sOut = sIn.match(/([\w\s]|: ?\)|: ?\(|: ?P)*/g).join('');

它在您嘗試的其他方面起作用 - 它找到所有“合法”字符/組合並將它們連接在一起。

問候

編輯:更新了正則表達式以處理表情符號中的可選空格(如前面所述)。

哈! 這個很有意思

更換

(?!(:\)|:\(|:P))[^a-zA-Z0-9 ](?<!(:\)|:\(|:P))

什么都沒有

我們的想法是,你使用相同的正則表達式將非法字符夾在一次作為負面看起來,而將其作為負面看起來。

結果將包含連續的空格。 這是正則表達式無法在1次掃描AFAIK中執行的操作,因為它無法同時查看多個匹配項。

要消除連續的空格,可以用\\s+替換\\s+ (一個空的空間)

這是一個更新的答案,符合表情符號可以包含空格的新要求

更換

((:\))|(:\()|(:P)|(: \))|: P)|[^0-9a-zA-Z\r\n ]

$1

在自由間隔模式下格式化成為

(?x)
(
  (?::\))|
  (?::\()|
  (?::P)|
  (?::\ \))|
  :\ P
)|
[^0-9a-zA-Z\r\n ]

在PHP中

$result = preg_replace('/((:\))|(:\()|(:P)|(: \))|: P)|[^0-9a-zA-Z\r\n ]/', '$1', $subject);

我們的想法是,我們使用包含多個字符的表情符號啟動正則表達式,這些表情符號可以包含非法字符。

該組被捕獲,后來用作替換$ 1

然后,在交替之后,我們使用我們否定的字符白名單,因此它將被匹配,但在替換的模式中將不會被提及。

所有不匹配的東西(我們的白名單)將按照慣例在結果中重復。

關於沒有的事情是在列出可能妨礙性能的表情符號時有很多分組。 為了防止這種情況,我們可以使正則表達式更冗長:

 ((?::\))|(?::\()|(?::P)|(?:: \))|: P)|[^0-9a-zA-Z\r\n ]

多個連續空間保留,並且無法在1次掃描AFAIK中求解。

這是一個字符串格式化程序,可以完成這項工作,假設表情符號通常為2個字符長:

<?php

class StringFormatter
{
  private $blacklist;
  private $whitelist;

  public function __construct(array $blacklist, array $whitelist)
  {
    $this->blacklist = $blacklist;
    $this->whitelist = $whitelist;
  }

  public function format($str)
  {
    $strLen = strlen($str);

    $result = '';
    $counter = 0;
    while ($counter < $strLen) {
      // get a character from the string
      $char = substr($str, $counter, 1);

      // if not blacklisted, allow it in the result
      if (!in_array($char, $this->blacklist)) {
        $result .= $char;
        $counter++;
        continue;
      }

      // if we reached the last letter, break out of the loop
      if ($counter >= $strLen - 1) {
        break;
      }

      // we assume all whitelisted entries have same length (e.g. 2
      // for emoticons)
      if (in_array(substr($str, $counter, 2), $this->whitelist)) {
        $result .= substr($str, $counter, 2);
        $counter += 2;
      } else {
        $counter++;
      }
    }

    return $result;
  }
}

// example usage
// $whitelist is not the entire whitelist, actually it's the exceptions
// to the blacklist, so more complext strings including blacklisted  characters that should be allowed
$formatter = new StringFormatter(['#', '_', ':', '!'], [':)', ':(']);
echo $formatter->format('Hi! Glad # to _ see : you :)');

上面的代碼可以進一步重構為更清晰,但你得到的圖片。

我用這個正則表達式,

(?i)(:\s*[)p(])(*SKIP)(*FAIL)|[^a-z0-9 ]

演示: https//regex101.com/r/nW6iL3/2

PHP用法:

$string = ':     ) instead of :)

or

:     P instead of :P

Hi! Glad # to _ see : you :)';

echo preg_replace('~(?i)(:\s*[)p(])(*SKIP)(*FAIL)|[^a-z0-9 ]~', '', $string);

輸出:

:)而不是:)或:P代替:PHi很高興見到你:)

演示: https//eval.in/416394

如果表情符號的結束部分發生變化,或者您有其他表情符號,則可以將其添加到此字符類[)p(]

您還可以通過將:更改為角色類來改變眼睛,這樣您就可以做到

(?i)([:;]\s*[)p(])(*SKIP)(*FAIL)|[^a-z0-9 ] 

如果你也想允許眨眼的臉(我認為分號是眨眼)..

更新

一點一點解釋......

(?i) =使正則表達式不敏感

: =尋找眼睛(冒號)

\\s* =搜索零或更多(*是前面字符的0或更多)空格字符( \\h在這里可能更好, \\s包括新行和制表符)

[)p(] =這是一個允許其中任何字符出現的字符類.so )p(允許在這里允許)。

(*SKIP)(*FAIL) =如果我們發現之前的正則表達式忽略了它,www.rexegg.com / regex-best -trick.html。

| =或

[^a-z0-9 ] - 一個否定的字符類,表示此列表中沒有的任何字符。

regex101還有正則表達式的文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM