[英]regex to remove all whitespaces except between brackets
我一直在努力解決我希望用正則表達式解決的問題。
假設我有一個字符串,可以包含任何字母數字,並且子字符串可能被方括號包圍。 這些子字符串可以像這樣出現在字符串中的任何位置。 也可以有任意數量的括號子串。
例子:
您可以看到某些括號中的子串中有空格,這很好。 我現在的主要問題是當我遇到括號外的空格時,如下所示:
現在我想保留括號內的空格,但在其他地方刪除它們。
對於像以下字符串來說,這會變得有點棘手:
在這里,我希望返回:
我現在花了一些時間閱讀不同的reg ex頁面關於lookarounds,負面斷言等等,這讓我頭暈目眩。
注意:對於訪問此文件的任何人,我並不是在尋找任何涉及嵌套括號的解決方案。 如果是這種情況,我可能會像下面提到的一些評論一樣務實地做。
這個正則表達式應該做的伎倆:
[ ](?=[^\]]*?(?:\[|$))
只需替換與“”匹配的空格即可。
基本上它所做的只是確保你要移除的空間前面有一個“[”,但如果它前面有一個“]”則沒有。
只要您沒有嵌套的方括號,這應該可以工作,例如:
aa [b [cc] b]
因為在這種情況下,第一個“b”之后的空格將被刪除,它將變為:
AA [B [CC] B]
這聽起來不像你真正想要的正則表達式。 通過閱讀直接解析非常容易。 偽代碼:
inside_brackets = false;
for ( i = 0; i < length(str); i++) {
if (str[i] == '[' )
inside_brackets = true;
else if str[i] == ']'
inside_brackets = false;
if ( ! inside_brackets && is_space(str[i]) )
delete(str[i]);
}
任何涉及正則表達式的東西都會涉及很多外觀的東西,這些東西會一遍又一遍地重復,而且它會慢得多,而且難以理解。
要使其適用於嵌套括號,只需將inside_brackets
更改為計數器,從零開始,在開括號上遞增,在小括號上遞減。
這對我有用:
(\[.+?\])|\s
然后,當您調用replace函數時,只需傳入$ 1的替換值。 我們的想法是首先在括號內查找圖案,並確保它們不受影響。 然后括號外的每個空格都被替換為空。
請注意,我使用Regex Hero(.NET正則表達式測試程序)進行了測試,而不是使用PHP進行測試。 所以我不是百分百肯定這會對你有用。
這是一個有趣的。 一開始聽起來很簡單,然后看起來相當困難。 然后我終於到達的解決方案確實很簡單。 我很驚訝解決方案不需要任何形式的外觀。 它應該比使用環視的任何方法更快。
如何做到這一點取決於應該做什么:
a b [ c [ d [ e ] f ] g
這是模棱兩可的; 可能的答案至少是:
ab[ c [ d [ e ] f ]g
ab[ c [ d [ e ]f]g
對於前兩種情況,您可以使用regexp。 對於第三種情況,使用(小)解析器會更好。
對於一個或兩個案例,將字符串拆分為第一個[
。 [
之前顯然在括號之外)從所有內容中刪除空格。 接下來,查找.*\\]
(案例1)或.*?\\]
(案例2)並將其移至輸出。 重復,直到你沒有輸入。
恢復這個問題,因為它有一個沒有提到的簡單解決方案。
\[[^]]*\](*SKIP)(*F)|\s+
交替的左側匹配完整的括號組,然后故意失敗。 右側匹配並捕獲第1組的空格,我們知道它們是正確的空格,因為如果它們在括號內,則左邊的表達式會失敗。
查看此演示中的匹配項
這意味着你可以做到
$replace = preg_replace("~\[[^]]*\](*SKIP)(*F)|\s+~","",$string);
參考
以下內容將匹配行首或行括結束(必須在您要匹配的任何空格之前),后跟任何不是括號或空格的內容,后跟一些空格。
/((^|\])[^ \[]*) +/
用$1
替換“all”將從每個非括號序列中刪除第一個空格塊。 您必須重復匹配才能刪除所有空格。
例:
abcd efg [hij klm]nop qrst u
abcdefg [hij klm]nopqrst u
abcdefg[hij klm]nopqrstu
done
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.