2015年8月27日 星期四

[Javascript] substr() & substring()

w3c substr()的解釋:
Extracts the characters from a string, beginning at a specified start position, and through the specified number of character.
簡單的講就是,指定開始位置與需要的長度抽取出子字串。index0開始。
語法:
"somestring".substr(start, length)
例子:
alert("12345".substr(2,3)); //會印出345
w3c substring()的解釋:
Extracts the characters from a string, between two specified indices.
substring()則是抽取出兩個index之間的子字串。index0開始。
語法:
"something".substring(from, to)

例子:
alert("12345".substring(2,3)); //會印出3

[Java Script] isNaN() 函數:判斷是否是非數值

定義和用法
isNaN() 函數用於檢查其參數是否是非數值。

語法:
isNaN(x)


參數: x

描述: 必需值。要檢測的值。

提示:isNaN() 函數通常用於檢測 parseFloat() 和 parseInt() 的結果,以判斷它們表示的是否是合法的數字。當然也可以用 isNaN() 函數來檢測算數錯誤,比如用 0 作除數的情況。

實例
isNaN();                   //返回 false
isNaN(0/0);                //返回 true 
isNaN(parseInt("3"));      //返回 false
isNaN(parseInt("hello"));  //返回 true 
isNaN("3");                //返回 false
isNaN("hello");            //返回 true 
isNaN(true);               //返回 false
isNaN(undefined);          //返回 true
如果 x 是特殊的非數位值 NaN(或者能被轉換為這樣的值),返回的值就是 true。
如果 x 是其他值,則返回 false。isNaN() 函數可用於判斷其參數是否是 NaN,該值表示一個非法的數字(比如被 0 除後得到的結果)。
如果把 NaN 與任何值(包括其自身)相比得到的結果均是 false,所以要判斷某個值是否是NaN,不能使用 == 或 === 運算符。
正因為如此,isNaN() 函數是必需的。

[Javascript] 正則替換去除字串中特定符號

用Javascript替換掉字串中的特殊符號

function clearString(s){ 
    var pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()&;|{}【】‘;:”“'。,、?]"
    var rs = ""
    for (var i = 0; i < s.length; i++) { 
        rs = rs+s.substr(i, 1).replace(pattern, ''); 
    } 
    return rs;  


想要過濾的字串在 RegExp()中自己進行設定,中文和英文的特殊符號可以替換。

[Javascript] 正規表示式

規則及運算符號

「*」符合 0 項以上

「|」符合 0 或 1 項以上

「+」符合 1 項以上

「?」符合 0 到 1 項



「( )」組合及排定運算順序

「[ ]」可接受出現的字元定義符號

「{ }」設定長度

「/ /」宣告 PCRE 正規表達式

「^ $」起始與結尾字符

「.」萬用字元,代表任何文字

「\」特殊字元 ^.$()|*+?{\ 前面必須加上此轉移字元



正規表達式範例


{2,4}、{3}、{3,}
分別代表 2-4 個字元、3個字元、3個以上字元

[a-z]
代表小寫英文

[A-Z]
代表大寫英文

[^A-Z]
代表大寫英文字母以外

[A-Za-z0-9_]
代表接受大小寫英數及符號

[A-Za-z]
代表大小寫英文

[0-9]
代表數字

[^0-9]
代表數字以外

[0-9A-Za-z]
代表英文大小寫及數字

[^A-Za-z0-9]
代表英文大小寫及數字以外

PCRE 正規表達式


\d
代表數字,等於 [0-9]

\D
代表數字以外,等於 [^0-9]

\w
代表包含底線的英文大小寫及數字,等於 [A-Za-z0-9_]

\W
代表包含底線英文大小寫及數字以外,等於 [^A-Za-z0-9_]

\b
代表一個單詞邊界,也就是指單詞和空格間的位置。
例如, ya\b 等於 “nahoya” 中的 ya,但不等於 “nahoyabe” 中的 ya

\B
代表非單詞邊界。
例如,ya\B 等於 “nahoyabe” 中的 ya,但不等於 “nahoya” 中的 ya

\s
代表非字元的對象,如 空白 及 Tab,等於 [ \f\n\r\t\v]

\S
代表非字元的對象以外,等於 [^ \f\n\r\t\v]

\n
代表換行字元

\t
代表 TAB

\/
代表反斜線 /

PCRE 正規表達式修改器


/…/i
忽略大小寫


/…/e
當成指令處理 

2013年10月17日 星期四

[JavaScript] trim函數大賞


W3C那幫人的腦袋被驢踢了,直到javascript1.8.1才支持trim函數(與trimLeft,trimRight),可惜現在只有firefox3.5支持。由於去除字符串兩邊的空白實在太常用,各大類庫都有它的影子。加之,外國人都很有研究精神,搞鼓了相當多實現。

實現1

 String.prototype.trim = function() {
  return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
} 
看起來不怎麼樣,動用了兩次正則替換,實際速度非常驚人,主要得益於瀏覽器的內部優化。一個著名的例子字符串拼接,直接相加比用Array做成的StringBuffer還快。 base2類庫使用這種實現。

實現2

 String.prototype.trim = function() {
  return this.replace(/^\s+/, '').replace(/\s+$/, '');
} 
和實現1很相似,但稍慢一點,主要原因是它最先是假設至少存在一個空白符。 Prototype.js使用這種實現,不過其名字為strip,因為Prototype的方法都是力求與Ruby同名。

實現3

 String.prototype.trim = function() {
  return this.substring(Math.max(this.search(/\S/), 0),this.search(/\S\s*$/) + 1);
} 
以截取方式取得空白部分(當然允許中間存在空白符),總共調用了四個原生方法。設計得非常巧妙,substring以兩個數字作為參數。 Math.max以兩個數字作參數,search則返回一個數字。速度比上面兩個慢一點,但比下面大多數都快。

實現4

 String.prototype.trim = function() {
  return this.replace(/^\s+|\s+$/g, '');
} 
這個可以稱得上實現2的簡化版,就是利用候選操作符連接兩個正則。但這樣做就失去了瀏覽器優化的機會,比不上實現3。由於看來很優雅,許多類庫都使用它,如JQuery與mootools

實現5

 String.prototype.trim = function() {
  var str = this;
  str = str.match(/\S+(?:\s+\S+)*/);
  return str ? str[0] : '';
} 
match是返回一個數組,因此原字符串符合要求的部分就成為它的元素。為了防止字符串中間的空白符被排除,我們需要動用到非捕獲性分組(?:exp)。由於數組可能為空,我們在後面還要做進一步的判定。好像瀏覽器在處理分組上比較無力,一個字慢。所以不要迷信正則,雖然它基本上是萬能的。

實現6

 String.prototype.trim = function() {
  return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, '$1');
} 
把符合要求的部分提供出來,放到一個空字符串中。不過效率很差,尤其是在IE6中。

實現7

 String.prototype.trim = function() {
  return this.replace(/^\s*(\S*(?:\s+\S+)*)\s*$/, '$1');
} 
和實現6很相似,但用了非捕獲分組進行了優點,性能效之有一點點提升。

實現8

 String.prototype.trim = function() {
  return this.replace(/^\s*((?:[\S\s]*\S)?)\s*$/, '$1');
} 
沿著上面兩個的思路進行改進,動用了非捕獲分組與字符集合,用?頂替了*,效果非常驚人。尤其在IE6中,可以用瘋狂來形容這次性能的提升,直接秒殺火狐。

實現9

 String.prototype.trim = function() {
  return this.replace(/^\s*([\S\s]*?)\s*$/, '$1');
} 
這次是用懶惰匹配頂替非捕獲分組,在火狐中得到改善,IE沒有上次那麼瘋狂。

實現10

 String.prototype.trim = function() {
  var str = this,
  whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000';
  for (var i = 0,len = str.length; i < len; i++) {
    if (whitespace.indexOf(str.charAt(i)) === -1) {
      str = str.substring(i);
      break;
    }
  }
  for (i = str.length - 1; i >= 0; i--) {
    if (whitespace.indexOf(str.charAt(i)) === -1) {
      str = str.substring(0, i + 1);
      break;
    }
  }
  return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
} 
我只想說,搞出這個的人已經不是用牛來形容,已是神一樣的級別。它先是把可能的空白符全部列出來,在第一次遍歷中砍掉前面的空白,第二次砍掉後面的空白。全過程只用了indexOf與substring這個專門為處理字符串而生的原生方法,沒有使用到正則。速度快得驚人,估計直逼上內部的二進制實現,並且在IE與火狐(其他瀏覽器當然也毫無疑問)都有良好的表現。速度都是零毫秒級別的。

實現11

 String.prototype.trim = function() {
  var str = this,
  str = str.replace(/^\s+/, '');
  for (var i = str.length - 1; i >= 0; i--) {
    if (/\S/.test(str.charAt(i))) {
      str = str.substring(0, i + 1);
      break;
    }
  }
  return str;
} 
實現10已經告訴我們普通的原生字符串截取方法是遠勝於正則替換,雖然是複雜一點。但只要正則不過於復雜,我們就可以利用瀏覽器對正則的優化,改善程序執行效率,如實現8在IE的表現。我想通常不會有人在項目中應用實現10,因為那個whitespace實現太長太難記了(當然如果你在打造一個類庫,它絕對是首先)。實現11可謂其改進版,前面部分的空白由正則替換負責砍掉,後面用原生方法處理,效果不遜於原版,但速度都是非常逆天。

實現12

 String.prototype.trim = function() {
  var str = this,
  str = str.replace(/^\s\s*/, ''),
  ws = /\s/,
  i = str.length;
  while (ws.test(str.charAt(--i)));
  return str.slice(0, i + 1);
} 
實現10與實現11在寫法上更好的改進版,注意說的不是性能速度,而是易記與使用上。和它的兩個前輩都是零毫秒級別的,以後就用這個來工作與嚇人。
下面是老外給出的比較結果,執行背景是對Magna Carta 這文章(超過27,600字符)進行trim操作。
實現Firefox 2IE 6
trim115ms< 0.5ms
trim231ms< 0.5ms
trim346ms31ms
trim447ms46ms
trim5156ms1656ms
trim6172ms2406ms
trim7172ms1640ms
trim8281ms< 0.5ms
trim9125ms78ms
trim10< 0.5ms< 0.5ms
trim11< 0.5ms< 0.5ms
trim12< 0.5ms< 0.5ms
原文鏈接:http://blog.stevenlevithan.com/archives/faster-trim-javascript

2013年7月31日 星期三

[C#] String常用技巧整理(IndexOf、LastIndexOf、Substring、Split)


String.IndexOf

String.IndexOf 方法 (Char, Int32, Int32)
報告指定字符在此範例中的第一個匹配項的索引。搜索從指定字符位置開始,並檢查指定數量的字符位置。
String.IndexOf(value, startIndex, count)

參數
value:要查找的 Unicode 字符。
startIndex:搜索起始位置。
count:要檢查的字符位置數。
返回值(Int32):
如果找到該字符,則為value 的索引位置;否則如果未找到,則為-1。

範例:
string str = "深圳市盈基實業有限公司國際通鄧事文*深圳市盈基實業有限公司國際通鄧事文";
Label1.Text = str.IndexOf("中國").ToString();//返回-1
Label1.Text = str.IndexOf("盈基").ToString();//返回3
Label1.Text = str.IndexOf("盈基",10).ToString();//返回21 說明:這是從第10個字符開始查起。
Label1.Text = str.IndexOf("鄧",15,10).ToString();//返回-1
Label1.Text = str.IndexOf("鄧",15,20).ToString();//返回-32 說明:從第15個字符開始查找,
要查找的範圍是從第15個字符開始後20個字符,即從第15-35個字符中查找。

<---------------------------------------------------------------------------------------------------------->

String.LastIndexOf

String.LastIndexOf 方法
報告指定的Unicode 字符或String 在此實例中的最後一個匹配項的索引位置。


名稱 說明
String.LastIndexOf (Char)報告指定Unicode 字符在此實​​例中的最後一個匹配項的索引位置。
String.LastIndexOf (String)報告指定的String 在此實例內的最後一個匹配項的索引位置。
String.LastIndexOf (Char, Int32)報告指定Unicode 字符在此實​​例中的最後一個匹配項的索引位置。該搜索從指定字符位置開始。
String.LastIndexOf (String, Int32)報告指定的String 在此實例內的最後一個匹配項的索引位置。該搜索從指定字符位置開始。
String.LastIndexOf (String, StringComparison)報告指定字符串在當前String 對像中最後一個匹配項的索引。一個參數指定要用於指定字符串的搜索類型。
String.LastIndexOf (Char, Int32, Int32)報告指定的Unicode 字符在此實​​例內的子字符串中的最後一個匹配項的索引位置。搜索從指定字符位置開始,並檢查指定數量的字符位置。
String.LastIndexOf (String, Int32, Int32)報告指定的String 在此實例內的最後一個匹配項的索引位置。搜索從指定字符位置開始,並檢查指定數量的字符位置。
String.LastIndexOf (String, Int32, StringComparison)報告指定字符串在當前String 對像中最後一個匹配項的索引。參數指定當前字符串中的起始搜索位置,以及要用於指定字符串的搜索類型。
String.LastIndexOf (String, Int32, Int32, 
StringComparison)
報告指定的String 對像在此實例內的最後一個匹配項的索引位置。參數指定當前字符串中的起始搜索位置、要搜索的當前字符串中的字符數量,以及要用於指定字符串的搜索類型。



範例:
string str = "深圳市盈基實業有限公司國際通鄧事文*深圳市盈基實業有限公司國際通鄧事文";
Label1.Text = str.LastIndexOf("鄧文").ToString();//返回-1
Label1.Text = str.LastIndexOf("鄧").ToString();//返回32

Label1.Text = str.LastIndexOf("鄧",8).ToString();//返回-1
Label1.Text = str.LastIndexOf("鄧",20).ToString();//返回14
Label1.Text = str.LastIndexOf("鄧",33).ToString();//返回32
說明:在指定的範圍內查找字符,這個範圍是上面的輸入的參數,
理解為,從索引0開始到指定的數值位置範圍內查找最後一個匹配的的字符串的位置。示例中,0-8中沒有“鄧”字,
所以返回-1,0-20範圍中,有一個“鄧”字在索引14位置上,0-33範圍中有兩個“鄧”字,
因為LastIndexOf是返回最後一個匹配項索引位置,所以返32,而不是14。

PS : IndexOf、LastIndexOf都是返回一個位置,是個整數值;找不到都返回-1;
IndexOf是從左向右查,LastIndexOf是從右向左查,不管是IndexOf還是LastIndexOf,
索引序列都是從左到右的(起始值是0)
<---------------------------------------------------------------------------------------------------------->
String.Substring

String.Substring 方法
從此實例檢索子字符串。
名稱 說明
String.Substring (Int32) 從此實例檢索子字符串。子字符串從指定的字符位置開始。
String.Substring (Int32, Int32) 從此實例檢索子字符串。子字符串從指定的字符位置開始且具有指定的長度。

示例:
string str = "深圳市盈基實業有限公司國際通鄧事文*深圳市盈基實業有限公司國際通鄧事文";
Label1.Text = str.Substring(11);//返回“國際通鄧事文*深圳市盈基實業有限公司國際通鄧事文”
Label1.Text = str.Substring(11,7);//返回“國際通鄧事文*”

<---------------------------------------------------------------------------------------------------------->

String.Split



1,用字符串分隔:


using System.Text.RegularExpressions;

string str="aaajsbbbjsccc";

string[] sArray=Regex.Split(str,"js",RegexOptions.IgnoreCase);

foreach (string i in sArray) Response.Write(i.ToString() + "<br>");


輸出結果:
aaa
bbb
ccc

2,用多個字符來分隔:


string str="aaajbbbscccjdddseee";

string[] sArray=str.Split(new char[2]{'j','s'});

foreach(string i in sArray) Response.Write(i.ToString() + "<br>");


輸出結果:
aaa
bbb
ccc
ddd
eee

3,用單個字符來分隔:

字符串str=“aaajbbbjccc”;

字符串[] sArray= str.Split(“J”);

的foreach(字符串sArray我)回复於(i.ToString()+“ - ”);

輸出結果:
aaa
bbb
ccc

轉自:http://a-jau.blogspot.tw/2012/01/cstringindexoflastindexofsubstringsplit.html

2013年5月6日 星期一

[JavaScript] 傳說中的 parseInt('08')

轉自:http://audi.tw/Blog/JavaScript/javascript.parseInt.asp
原文發布時間:6/3 08' 


眾所周知,parseInt() 是用來把字串轉換成整數的函式,一般來說,只要是數字開頭的字串,都能夠轉換成功,例如 parseInt('123a') 的結果為 123,parseInt('12 34') 的結果為12。
關於 parseInt() 有個著名的情況,有些人稱為臭蟲,讓各位自己來評斷。

parseInt('01') 得出的結果是1,事實上,一直到 07 為止,都能得到預期結果,問題來了,parseInt('08') 和 parseInt('09') 這兩者運算的結果,都得到0,這是為什麼呢?

主要原因在於 parseInt() 這個函式,本身可以傳遞兩個參數,語法是:
parseInt(string, radix)
第一個參數 string 當然是要轉換為數字的字串,第二個參數 radix 則是要用二進位、還是八進位或十六進位,又或是最熟悉的十進位來解譯這個字串呢?

也就是說,如果 parseInt('FF',16),代表以 16 進位方式來解析FF這個字串,當然得到的結果就是 255 了,同理,parseInt('FF',10) 以 10 進位來解析FF這個字串,根本就不是數字,所以得到的結果會是 NaN。

但大多數人不會特別指定第二個參數,這時 JavaScript 就自動判斷第一個傳遞的參數是否為某種數字型式。

在 JavaScript 眼中,以 0x 開頭的字串,都視為十六進位字串,如果單單是0開頭,第二個字母不是 x,則視為八進位或二進位字串,
十六進位使用的字母計有 0-9,A-F,而八進位使用的字母則為 0-7,所以,當發生parseInt('08') 又未指定以何種數值型態解析時,JavaScript 以 0 為起頭,接下來的字母又不是 x,那一定是八進位了,但是,八進位裡,怎麼可能有 8 和 9 這兩個字母呢?所以,一定是不合法的字串,於是就傳回 0。

同理,parseInt('010') 回傳的值,也不是 10,而是 8,因為 parseInt() 認為 0 開頭,接下來的字母不是 x,而是 1,就以二進位來解析 010 這個字串,所以一切問題都在於以 0 開頭,所造成的誤會。

最好的解決辦法,就是別偷懶,把第二個參數也加進去,例如 parseInt('08',10)、parseInt('010',10),那就萬無一失了!