![](/img/trans.png)
[英]Regex to remove non-alphanumeric characters and all characters after dot?
[英]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.