2015-02-07 126 views
0

我想寫一個正則表達式,使得接下來的事情就替換字符:取出並通過正則表達式

  1. _ - 用空格>替換
  2. + - >刪除它,如果沒有另一個+後(即c++ =>c++c+ - >c
  3. ' - >中刪除它,如果它在該單詞的開始或結束(即 Alin's - >Alin's'Alin's - >alin's
  4. &-.,! - 不要刪除。
  5. 另一個特殊字符 - 刪除

我想這樣做,通過傳遞一個時間字符串

例如:

Input: "abc's, test_s! & c++ c+ 'Dirty's'. and beautiful'..." 
Output: "abc's test s! & c++ c Dirty's. and beautiful..." 

說明:

char `'` in `abc's,` stays because `3` 
char `,` in `abc's,` was removed because `5` 
char `_` in `test_s!` was replaced by space because `1` 
char `!` in `test_s!` is not removed because `!` 
char `&` is not removed because `4` 
char `+` in `c++` is not removed because `2` 
char `+` in `c+` was removed because `2` 
word: `'Dirty's'.` was replaced to `Dirty's.` because `3` and `4` 
char `'` in `beautiful'...` was removed because `3` 
char `.` is not removed because of `4` 

這是我的javascript代碼:

var str = "abc's test_s c++ c+ 'Dirty's'. and beautiful"; 
console.log(str); 
str = str.replace(/[_]/g, " "); 
str = str.replace(/[^a-zA-Z0-9 &-.!]/g, ""); 
console.log(str); 

這是我的jsfiddle:http://jsfiddle.net/alonshmiel/LKjYd/4/

我不喜歡我的代碼,因爲我敢肯定,它可能通過運行一次在字符串做。

任何幫助表示讚賞!

+1

什麼是您給這個數據'「ABC的test_s輸出C++ c +'骯髒的'。和美麗的'' – 2015-02-07 14:10:57

+0

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter – 2015-02-07 14:11:12

+0

@AhosanKarimAsik,輸出是: 「Abc's test s C++ c Dirty's 。和美麗的「 – 2015-02-15 16:01:44

回答

3

function sanitize(str){ 
 

 
    return str.replace(/(_)|(\'\W|\'$)|(^\'|\W\')|(\+\+)|([a-zA-Z0-9\ \&\-\.\!\'])|(.)/g,function(car,p1,p2,p3,p4,p5,p6){ 
 

 
    if(p1) return " "; 
 
    if(p2) return sanitize(p2.slice(1)); 
 
    if(p3) return sanitize(p3.slice(0,-1)); 
 
    if(p4) return p4.slice(0,p4.length-p4.length%2); 
 
    if(p5) return car; 
 
    if(p6) return ""; 
 
}); 
 
} 
 
document.querySelector('#sanitize').addEventListener('click',function(){ 
 
    
 
    document.querySelector('#output').innerHTML=  
 
\t sanitize(document.querySelector('#inputString').value); 
 
});
#inputString{ 
 
    width:290px 
 
} 
 
#sanitize{ 
 
    background: #009afd; 
 
    border: 1px solid #1777b7; 
 
    border:none; 
 
    color:#fff; 
 
    cursor:pointer; 
 
    height: 1.55em; 
 
} 
 

 
#output{ 
 
    background:#ddd; 
 
    margin-top:5px; 
 
    width:295px; 
 
}
<input id="inputString" type="text" value="abc's test_s! & c++ c+ 'Dirty's'. and beau)'(tiful'..."/> 
 
<input id="sanitize" type="button" value="Sanitize it!"" /> 
 
<div id="output" ></div>

幾點:

  • 一個通約束沒有得到充分尊重,由於消毒與\ W拍攝的人物的義務。我沒有找到任何其他方式。
  • 關於++規則:如果損害,+的任何序列都減1。
  • 只有在旁邊有一個非字母數字字符的情況下,纔會刪除apostrophs。你應該怎麼做,例如:「abc'&」。 「abc &」或「abc'&」?也適用於「ab_'s」。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter

1

你需要的是鏈接和交替操作

function customReplace(str){ 
    return str.replace(/_/g, " ").replace(/^'|'$|[^a-zA-Z0-9 &-.!]|\+(?=[^+])/g,""); 
} 

正則表達式/^'|'$|[^a-zA-Z0-9 &-.!]|\+(?=[^+])/g什麼結合了所有需要被刪除。我們用一個空格替換所有的_,我們最終返回。

\+(?=[^+])查找+後跟任何東西,除了+

另外,的更換順序很重要。

+0

這會刪除'C++'中的第二個'+',這似乎並不是OP所需要的。您可能還需要包含預見以確保只刪除獨立'+' 秒。 – 2015-02-16 07:47:30

2

由於您需要的替換可能不同(無或空格),因此無法使用固定字符串(由於單通約束)。所以唯一的辦法是使用動態替換。

直接的方法:

讓我們嘗試查找的字符去掉,並在某些情況下,他人保留:

var str = "abc's, test_s! & c++ c+ 'Dirty's'. and beautiful'..."; 

var re = /[^\w\s&.!'+-]+|\B'+|'+\B|(\+{2,})|\+|'*(_)'*/g; 

var result = str.replace(re, function (_, g1, g2) { 
    if (g1) return g1; 
    return (g2) ? ' ' : ''; }); 

console.log(result); 

當下劃線被發現,捕獲組2被定義(回調函數中的g2)並返回一個空格。

注意:在上面的例子中,術語「單詞」是以正則表達式的意思(除了下劃線之外,字符類別\w所以[a-zA-Z0-9_]),但是如果您想要更嚴格,例如要排除單引號附近數字,你需要改變的模式有點:關於這兩個模式

var re = /[^\w\s&.!'+-]+|(_)'*|([^a-z])'+|'+(?![a-z])|(\+{2,})|\+|^'+/gi; 

var result = str.replace(re, function (_, g1, g2, g3) { 
    if (g2) return g2; 
    if (g3) return g3; 
    return (g1) ? ' ' : ''; }); 

注:

這兩種模式由在6點或7的子模式的交替,可以匹配大約1或2個字符最時間。請記住,要找到要刪除的角色,這些模式必須先測試6個或7個替代品,然後才能對每個不能替換的角色進行失敗。這是一項重要的成本,大部分時間角色不需要被替換。

還有就是要降低這一成本,你可以在這裏申請辦法:第一個字符識別

這樣做是爲了避免儘可能多地測試每個子模式。這可以在這裏完成,因爲所有的子模式都不以字母開頭,所以如果你在開始處添加一個前瞻,你可以快速跳過所有字母,而不必測試每個子模式。例如,對於模式2:

var re = /(?=[^a-z])(?:[^\w\s&.!'+-]+|(_)'*|([^a-z])'+|'+(?![a-z])|(\+{2,})|\+|^'+)/gi; 

對於第一圖案可以跳過多個字符:

var re = /(?=[^a-z0-9\s&.!-])(?:[^\w\s&.!'+-]+|\B'+|'+\B|(\+{2,})|\+|'*(_)'*)/gi; 

儘管有這些改進,這兩個圖案需要很多步驟對於小字符串(〜400)(但認爲這是一個包含所有可能情況的示例字符串)

更間接的方法:

現在,讓我們嘗試由找到一個字符替換等方式,但這次與之前的所有字符。

var re = /((?:[a-z]+(?:'[a-z]+)*|\+{2,}|[\s&.!-]+)*)(?:(_)|.)?/gi 

var result = str.replace(re, function (_, g1, g2) { 
    return g1 + ((g2) ? ' ' : ''); 
}); 

(請注意,有沒有必要,以防止災難性的回溯,因爲(?:a+|b+|c+)*後面是一個始終保持正確的子模式(?:d|e)?。除此之外,整個模式將永遠不會失敗的任何字符串或它的位置。)

要替換的字符前的所有字符(允許的內容)被捕獲並由回調函數返回。

這種方式需要多於2倍的步驟來完成相同的工作。

1

試試這個:用正則表達式/(?!\b)'|'(?=\B)|^'|'$|[^\w\d\s&-.!]|\+(?=[^+])/gm

function sanitize(str) { 
 
    var re = /(?!\b)'|'(?=\B)|^'|'$|[^\w\d\s&-.!]|\+(?=[^+])/gm; 
 
    var subst = ''; 
 
    var tmp = str.replace(re, subst); // remove all condition without (_) 
 
    var result = tmp.replace("_", " "); // next replace (_) by () space. 
 
    return result; 
 
} 
 

 
document.querySelector('#sanitize').addEventListener('click', function() { 
 

 
    document.querySelector('#output').innerHTML = 
 
    sanitize(document.querySelector('#inputString').value); 
 
});
#inputString { 
 
    width: 290px 
 
} 
 
#sanitize { 
 
    background: #009afd; 
 
    border: 1px solid #1777b7; 
 
    border: none; 
 
    color: #fff; 
 
    cursor: pointer; 
 
    height: 1.55em; 
 
} 
 
#output { 
 
    background: #eee; 
 
    margin-top: 5px; 
 
    width: 295px; 
 
}
<input id="inputString" type="text" value="abc's test_s! & c++ c+ 'Dirty's'. and beau)'(tiful'..." /> 
 
<input id="sanitize" type="button" value="Sanitize it!" /> 
 
<div id="output"></div>