日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

过滤ASCII码中的不可见字符, ASCII三部分, 各控制字符详解, 去^@,^M

發布時間:2024/8/24 综合教程 40 生活家
生活随笔 收集整理的這篇文章主要介紹了 过滤ASCII码中的不可见字符, ASCII三部分, 各控制字符详解, 去^@,^M 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天產品部同事報告了一個BUG,經過調試發現,由于用戶輸入的字符串中,包含字符0x1E, 也就是”記錄分隔符”(Record Separator, Notepad++ 顯示為[RS]),導致JavaScript XML解析遭遇錯誤。于是就想在字符串中過濾掉這些沒多大用途的字符,同時又要保留部分常用的字符,例如換行,回車和水平制表符。于是寫了下面一個 PHP 函數:

/**
* 清理字符串中的部分不可見控制字符
*
* @param string $string 待處理字符串
* @return string 處理后的字符串
* @author fising(at)qq.com
*/
public static function clearInvisibleCharacter($string = '')
{
/* 排除 tab, 
,  三個字符 */
$do_not_searches = array(chr(9), chr(10), chr(13));
/* 需清理的字符列表 */
$searches = array(); 
for ($i = 0; $i <= 31; $i++)
{
if (!in_array(chr($i), $do_not_searches))
{
$searches[] = chr($i);
}
} 
$searches[] = chr(127); 
return str_replace($searches, '', $string);
}

過濾ASCII碼中的不可見字符

上面所說的“不可見字符”,其實屬于ascii碼中的控制字符,它們是0到31、以及127,分別代表什么可查詢ascii碼表。

在展示頁面前,將文字中的控制字符改為空格(ascii32)

public static String filter(String content){
if (content != null && content.length() > 0) {
char[] contentCharArr = content.toCharArray();
for (int i = 0; i < contentCharArr.length; i++) {
if (contentCharArr[i] < 0x20 || contentCharArr[i] == 0x7F) {
contentCharArr[i] = 0x20;
}
}
return new String(contentCharArr);
}
return "";
}

其具體每個控制字符的含義,詳解介紹如下:

【ASCII中的Function/Control Code功能字符的詳細含義】

0 – NUL –NULl字符/空字符

ASCII字符集中的空字符,NULL,起初本意可以看作為NOP(中文意為空操作,就是啥都不做的意思),此位置可以忽略一個字符。

之所以有這個空字符,主要是用于計算機早期的記錄信息的紙帶,此處留個NUL字符,意思是先占這個位置,以待后用,比如你哪天想起來了,在這個位置在放一個別的啥字符之類的。

后來呢,NUL字符被用于C語言中,字符串的終結符,當一個字符串中間出現NUL / NULL,代碼里面表現為,的時候,就意味著這個是一個字符串的結尾了。這樣就方便按照自己需求去定義字符串,多長都行,當然只要你內存放得下,然后最后加一個,即空字符,意思是當前字符串到此結束。

1 – SOH –Start
OfHeading
標題開始

如果信息溝通交流主要以命令和消息的形式的話,SOH就可以用于標記每個消息的開始。

1963年,最開始ASCII標準中,把此字符定義為Start of Message,后來又改為現在的Start Of Heading。

現在,這個SOH常見于主從(master-slave)模式的RS232的通信中,一個主設備,以SOH開頭,和從設備進行通信。這樣方便從設備在數據傳輸出現錯誤的時候,在下一次通信之前,去實現重新同步(resynchronize)。如果沒有一個清晰的類似于SOH這樣的標記,去標記每個命令的起始或開頭的話,那么重新同步,就很難實現了。

2 – STX –StartOfText文本開始

3 – ETX –End OfText文本結束

通過某種通訊協議去傳輸的一個數據(包),稱為一幀的話,常會包含一個幀頭,包含了尋址信息,即你是要發給誰,要發送到目的地是哪里,其后跟著真正要發送的數據內容。

而STX,就用于標記這個數據內容的開始。接下來是要傳輸的數據,最后是ETX,表明數據的結束。

其中,中間具體傳輸的數據內容,ASCII規范并沒有去定義,其和你所用的傳輸協議,具體自己要傳什么數據有關。

幀頭

數據或文本內容

SOH(表明幀頭開始)

。。。。(幀頭信息,比如包含了目的地址,表明你發送給誰等等)

STX(表明數據開始)

。。。(真正要傳輸的數據)

ETX(表明數據結束)

不過其中有趣的是,1963年,ASCII標準最初版本的時候,把現在的STX叫做EOA(End Of Address),ETX叫做(End Of Message)。這是因為,最早的時候,一個消息中,總是包含一個開始符和一個終止符。現在的新的定義,使得可以去發送一個固定長度的命令,而只用一個SOH表明幀頭開始即可,而不需要再加上一個命令終止符或幀頭結束符。

總結一下:

一般發送一個消息,包含了一個幀頭和后面真正要傳的數據。

而對于幀頭,屬于控制類的信息,這部分之前屬于命令,后面的真實要傳的數據屬于數據。即消息=幀頭+數據。

而之前的命令都要有個開始符和結束符,這樣就是:

消息
=幀頭
+要傳的數據

=幀頭開始+幀頭信息+幀頭結束
+要傳的數據

而現在新的定義,使得只需要:

消息
=幀頭+要傳的數據

= SOH(表明幀頭開始)+幀頭信息
+要傳的數據

= SOH(表明幀頭開始)+幀頭信息
+ STX +數據內容+ETX

就可以少用一個幀頭結束符。

而如今,在很多協議中,也常見到,一個固定長度的幀頭,后面緊接著就是數據了,而沒有所謂的幀頭結束符之類的東西去區分幀頭和數據。

4 – EOT –EndOfTransmission傳輸結束

5 – ENQ –ENQuiry請求

6 – ACK –ACKnowledgment回應/響應

7 – BEL – [audible]BELl

在ASCII字符集中,BEL,是個比較有意思的東東。因為其原先本意不是用來數據編碼的,于此相反,ASCII中的其他字符,都是用于字符編碼(即用什么字符,代表什么含義)或者起到控制設備的作用。BEL用一個可以聽得見的聲音,來吸引人們的注意,其原打算即用于計算機也用于一些設備,比如打印機等。C語言里面也支持此BEL,用a來實現這個響鈴。

8 – BS –BackSpace退格鍵

退格鍵的功能,隨著時間變化,意義也變得不同了。

起初,意思是,在打印機和電傳打字機上,往回移動一格光標,以起到強調該字符的作用。比如你想要打印一個a,然后加上退格鍵后,就成了aBS^。在機械類打字機上,此方法能夠起到實際的強調字符的作用,但是對于后來的CTR下時期來說,就無法起到對應效果了。

而現代所用的退格鍵,不僅僅表示光標往回移動了一格,同時也刪除了移動后該位置的字符。在C語言中,退格鍵可以用表示。

9 – HT –HorizontalTab水平制表符

ASCII中的HT控制符的作用是用于布局的。

其控制輸出設備前進到下一個表格去處理。而制表符Table/Tab的寬度也是靈活不固定的,只不過,多數設備上,制表符Tab的寬度都預定義為8。水平制表符HT不僅能減少數據輸入者的工作量,對于格式化好的文字來說,還能夠減少存儲空間,因為一個Tab鍵,就代替了8個空格,所以說省空間。

對于省空間的優點,我們現在來看,可能會覺得可笑,因為現在存儲空間已足夠大,一般來說根本不會需要去省那么點可憐的存儲空間,但是實際上在計算機剛發明的時候,存儲空間(主要指的是內存)極其有限也極其昂貴,而且像ZIP等壓縮方法也還沒發明呢,所以對于當時來說,對于存儲空間,那是能夠省一點是一點,省任何一點,都是好的,也都是不容易的,省空間就是省錢啊。

C語言中,用 表示制表符。

10 – LF –LineFeed換行

LF,直譯為(給打印機等)喂一行,意思就是所說的,換行。

換行字符,是ASCII字符集中,被誤用的字符中的其中一個。

LF的最原始的含義是,移動打印機的頭到下一行。而另外一個ASCII字符,CR(Carriage Return)才是將打印機的頭,移到最左邊即一行的開始,行首。很多串口協議和MS-DOS及Windows操作系統,也都是這么實現的。

而于此不同,對于C語言和Unix操作系統,其重新定義了LF字符的含義為新行,即LF和CR的組合才能表達出的,回車且換行的意思。

雖然你可以爭論哪種用法是錯的,但是,不可否認,是從程序的角度出發,C語言和Unix對此LF的含義實現顯得就很自然,而MS-DOS的實現更接近于LF的本意。

如果最開始ASCII標準中,及定義CF也定義newline,那樣意思會清楚,會更好理理解:

LF表示物理上的,設備控制方面的移動到下一行(并沒有移動到行首);

新行(newline)表示邏輯上文本分隔符,即回車換行。

不過呢,現在人們常將LF用做newline新行的功能,而大多數文本編輯軟件也都可以處理單個LF或者CR/LF的組合了。

LF在C語言中,用
表示。

11 – VT –VerticalTab垂直制表符

垂直制表符,類似于水平制表符Tab,目的是為了減少布局中的工作,同時也減少了格式化字符時所需要存儲字符的空間。VT控制碼用于跳到下一個標記行。說實話,還真沒看到有些地方需要用這個VT呢,因為一般在換行的時候,都是用LF代替VT了。

12 – FF –FormFeed
換頁

設計換頁鍵,是用來控制打印機行為的。當打印機收到此鍵碼的時候,打印機移動到下一頁。不同的設備的終端對此控制碼所表現的行為各不同。有些會去清除屏幕,而其他有的只是顯示^L字符或者是只是新換一行而已。Shell腳本程序Bash和Tcsh的實現方式是,把FF看作是一個清除屏幕的命令。C語言程序中用f表示FF(換頁)。

13 – CR – Carriage return機器的滑動部分/底座
返回->回車

CR回車的原意是讓打印頭回到左邊界,并沒有移動到下一行。

隨著時間流逝,后來人把CR的意思弄成了Enter鍵,用于示意輸入完畢。在數據以屏幕顯示的情況下,人們在Enter的同時,也希望把光標移動到下一行。因此C語言和Unix操作系統,重新定義了LF的意思,使其表示為移動到下一行。當輸入CR去存儲數據的時候,軟件也常常隱式地將其轉換為LF。

14 – SO –ShiftOut不用切換

15 – SI –ShiftIn
啟用切換

早在1960s年代,定義ASCII字符集的人,就已經懂得了,設計字符集不單單可以用于英文字符集,也要能應用于外文字符集,是很重要的。

定義Shift In和Shift Out的含義,即考慮到了此點。

最開始,其意為在西里爾語和拉丁語之間切換。西里爾ASCII定義中,KOI-7用到了Shift字符。拉丁語用Shift去改變打印機的字體。在此種用途中,SO用于產生雙倍寬度的字符,而用SI打印壓縮的字體。

16 – DLE –DataLinkEscape數據鏈路轉義

有時候,我們需要在正在進行的通信過程中去發送一些控制字符。但是,總有一些情況下,這些控制字符卻被看成了普通的數據流,而沒有起到對應的控制效果。而ASCII標準中,定義DLE來解決這類問題。

如果數據流中檢測到了DLE,數據接收端則對其后面接下來的數據流中的字符,另作處理。而關于具體如何處理這些字符,ASCII規范中則沒有具體定義,而只是弄了個DLE去打斷正常數據的處理,告訴接下來的數據,要特殊對待。根據Modem中的Hayes通信協議DLE定義為“無聲+++無聲”。以我的觀點,這樣可能會更好:如果Hayes協議沒有把DLE處理為嵌入通訊的無聲狀態,那樣就符合現存的標準了。然而Hayes的開發者卻覺得+++用的頻率要遠高于原始的DLE,所以才這么定義了。

17 – DC1 –DeviceControl 1 / XON – Transmission on

這個ASCII控制字符盡管原先定義為DC1,
但是現在常表示為XON,用于串行通信中的軟件流控制。其主要作用為,在通信被控制碼XOFF中斷之后,重新開始信息傳輸。用過串行終端的人應該還記得,當有時候數據出錯了,按Ctrl+Q(等價于XON)有時候可以起到重新傳輸的效果。這是因為,此Ctrl+Q鍵盤序列實際上就是產生XON控制碼,其可以將那些由于終端或者主機方面,由于偶爾出現的錯誤的XOFF控制碼而中斷的通信解鎖,使其正常通信。

18 – DC2 –DeviceControl 2

19 – DC3 –DeviceControl 3 / XOFF – Transmission off傳輸中斷

20 – DC4 –DeviceControl 4

21 – NAK –NegativeAcKnowledgment負面響應->無響應,非正常響應

22 – SYN –SYNchronous idle

23 – ETB –End ofTransmissionBlock塊傳輸中止

24 – CAN –CANcel取消

25 – EM –End ofMedium
已到介質末端,介質存儲已滿

EM用于,當數據存儲到達串行存儲介質末尾的時候,就像磁帶或磁頭滾動到介質末尾一樣。其用于表述數據的邏輯終點,即不必非要是物理上的達到數據載體的末尾。

26 – SUB –SUBstitute character替補/替換

27 – ESC –ESCape逃離/取消

字符Escape,是ASCII標準的首創的,由Bob Bemer提議的。用于開始一段控制碼的擴展字符。如此,即可以不必將所有可能想得到的字符都放到ASCII標準中了。因為,新的技術可能需要新的控制命令,而ESC可以用作這些字符命令的起始標志。ESC廣泛用于打印機和終端,去控制設備設置,比如字體,字符位置和顏色等等。如果最開始的ASCII標準中,沒有定義ESC,估計ASCII標準早就被其他標準所替代了,因為其沒有包含這些新出現的字符,所以肯定會有其他新的標準出現,用于表示這些字符的。即,ESC給開發者提供了,可以根據需要而定義新含義的字符的可能。

28 – FS –FileSeparator文件分隔符

文件分隔符是個很有意思的控制字符,因為其可以讓我們看到1960s年代的時候,計算機技術是如何組織的。我們現在,習慣于隨即訪問一些存儲介質,比如RAM,磁盤,但是在定義ASCII標準的那個年代,大部分數據還是順序的,串行的,而不是隨機訪問的。此處所說的串行的,不僅僅指的是串行通信,還指的是順序存儲介質,比如穿孔卡片,紙帶,磁帶等。在串行通信的時代,設計這么一個用于表示文件分隔符的控制字符,用于分割兩個單獨的文件,是一件很明智的事情。而FS的原因就在于此。

29 – GS –GroupSeparator分組符

ASCII定義控制字符的原因中,其中一條就是考慮到了數據存儲方面的情況。大部分情況下,數據庫的建立,都和表有關,包含了對應的記錄。同一個表中的所有的記錄,屬于同一類型。不同的表中的記錄,屬于對應的不同的類型。而分組符GS就是用來分隔串行數據存儲系統中的不同的組。值得注意的是,當時還沒有使用word的表格,當時ASCII時代的人,把他叫做組。

30 – RS –RecordSeparator記錄分隔符

記錄分隔符RS用于分隔在一個組或表內的多個記錄。

31 – US –UnitSeparator單元分隔符

在ASCII定義中,在數據庫中所存儲的,最小的數據項,叫做Unit單元。而現在我們稱其field域。單元分隔符US用于分割串行數據存儲環境下的不同的域。

現在大部分的數據庫實現,要求大部分類型都擁有固定的長度。

盡管大部分時候可能用不到,但是對于每一個域,卻都要分配足夠大的空間,用于存放最大可能的成員變量。這樣的做法,占用了大量的存儲空間,而US控制碼允許域具有可變的長度。在1960s年代,數據存儲空間很有限,用US這個單元分隔符,將不同單元分隔開,這樣就可以實現更高效地存儲那些寶貴的數據。另一方面,串行存儲的存儲效率,遠低于RAM和磁盤中所實現的表格存儲。我個人無法想象,如果現在的數據,還是存儲在自帶或者帶滾輪的磁帶上,會是何種景象。

32 – SP – WhiteSPace空格鍵

也許你會爭論說,空格鍵是否真的能算是一個控制字符?因為現在在普通文字中使用空格鍵是如此常見。

但是,既然水平制表符和退格鍵在ASCII中,都被叫做控制字符了,那么我覺得也很自然地,可以把空格鍵(向前的空格)也叫做控制字符,畢竟,其本身并不代表一個真正的可見的字符,而僅僅只是很常用于輸出設備,用于處理位置前向移動一格,清除當前位置的內容而已。在很多程序中,比如字符處理程序,白空格同樣可能從導致行尾轉到下一行行首,而網絡瀏覽器將多個空格組合成單個空格輸出。

所以,這更加堅定了我的想法,覺得完全可以把空格看成是一個控制字符,而不僅僅是一個很獨特的普通字符。

127 – DEL –DELete
刪除

有人也許會問,為何ASCII字符集中的控制字符的值都是很小的,即0-32,而DEL控制字符的值卻很大,是127。這是由于這個特殊的字符是為紙帶而定義的。而在那個時候,絕大多數的紙帶,都是用7個孔洞去編碼數據的。而127這個值所對應的二進制值為111 1111b,表示所有7個比特位都是高,所以,將DEL用在現存的紙帶上時,所有的洞就都被穿孔了,就把已經存在的數據都擦出掉了,就起到了對應的刪除的作用了。

【各種字符的標準的讀法/叫法】

常見ASCII字符,以及其他非常見的字符,Unicode中的字符,其他特殊字符等等,這些字符的英文叫法,可以去Unicode官方找到:

http://www.unicode.org/charts/

比如:

ASCII字符/字母的叫法/讀法
如何讀

1. C0 Control and Basic Latin Range:0000-007F

http://www.unicode.org/charts/PDF/U0000.pdf

2.Alphabetic Presentation Forms Range:FB00-FB4F
http://www.unicode.org/charts/PDF/UFB00.pdf

3.CJK Compatibility Forms

http://www.unicode.org/charts/PDF/UFE30.pdf

4.Fullwidth ASCII Punctuation

http://www.unicode.org/charts/PDF/UFF00.pdf

【引用】

1.C0 and C1 control codes

http://en.wikipedia.org/wiki/C0_and_C1_control_codes

2. Control Character

http://en.wikipedia.org/wiki/Control_character

3.
ASCII character map

http://www.lammertbies.nl/comm/info/ascii-characters.html

4.
百度百科:ASCII

http://baike.baidu.com/view/15482.htm

5.ASCII編碼表

http://www.dreamdu.com/xhtml/ascii/

ASCII碼大致可以分作三部分組成。

第一部分:ASCII非打印控制字符表

ASCII表上的數字0–31分配給了控制字符,用于控制像打印機等一些外圍設備。例如,12代表換頁/新頁功能。此命令指示打印機跳到下一頁的開頭。(參詳ASCII碼表中0-31)

第二部分:ASCII打印字符

數字 32–126 分配給了能在鍵盤上找到的字符,當您查看或打印文檔時就會出現。數字127代表 DELETE 命令。(參詳ASCII碼表中32-127)

ASCII碼表 0-127

第三部分:擴展ASCII打印字符

擴展的ASCII字符滿足了對更多字符的需求。擴展的ASCII包含ASCII中已有的128個字符(數字0–32顯示在下圖中),又增加了128個字符,總共是256個。即使有了這些更多的字符,許多語言還是包含無法壓縮到256個字符中的符號。因此,出現了一些ASCII的變體來囊括地區性字符和符號。例如,許多軟件程序把ASCII表(又稱作ISO8859-1)用于北美、西歐、澳大利亞和非洲的語言。

Vim里常見的幾個不可見字符:
^@ = 0x00 Null值
^H = 0x08 退格
^I = 0x09 水平制表
^J = 0x0A 換行
^M = 0x0D 回車

去掉^M回車:

:%s/^M//g # vi中將^M替換成回車。
$ sed -e 's/^M//g' myfile.txt #直接操作文件
注意:這里的“^M”要使用“CTRL-V CTRL-M”生成,而不是直接鍵入“^M”。

去掉^@:

sed -r 's/x0//g' file>file1

cat -v file打印不可見字符。


【什么是Function Code功能碼或Function Character功能字符】

ASCII字符集,大家都知道吧,最基本的包含了128個字符。其中前32個,0-31,即0x00-0x1F,都是不可見字符。這些字符,就叫做控制字符。

這些字符沒法打印出來,但是每個字符,都對應著一個特殊的控制功能的字符,簡稱功能字符或功能碼Function Code。

簡言之:ASCII中前32個字符,統稱為Function Code功能字符。

此外,由于ASCII中的127對應的是Delete,也是不可見的,所以,此處根據筆者的理解,也可以歸為Function Code。

此類字符,對應不同的“功能”,起到一定的“控制作用”,所以,稱為控制字符。

關于每個控制字符的控制功能縮寫,參見下表:

表格1
ASCII中的控制字符

進制

十六

進制

控制

字符

轉義

字符*

說明

Ctrl +

下列字母*

0

00

NUL

Null character(空字符)

@ (Shift + 2)

1

01

SOH

Start of Header(標題開始)

^A

2

02

STX

Start of Text(正文開始)

^B

3

03

ETX

End of Text(正文結束)

^C

4

04

EOT

End of Transmission(傳輸結束)

^D

5

05

ENQ

Enquiry(請求)

^E

6

06

ACK

Acknowledgment(收到通知/響應)

^F

7

07

BEL

a

Bell(響鈴)

^G

8

08

BS

Backspace(退格)

^H

9

09

HT

Horizontal Tab(水平制表符)

^I

10

0A

LF


Line feed(換行鍵)

^J

11

0B

VT

v

Vertical Tab(垂直制表符)

^K

12

0C

FF

f

Form feed(換頁鍵)

^L

13

0D

CR

Carriage return(回車鍵)

^M

14

0E

SO

Shift Out(不用切換)

^N

15

0F

SI

Shift In(啟用切換)

^O

16

10

DLE

Data Link Escape(數據鏈路轉義)

^P

17

11

DC1

Device Control 1(設備控制1) /XON(Transmit On)

^Q

18

12

DC2

Device Control 2(設備控制2)

^R

19

13

DC3

Device Control 3(設備控制3) /XOFF(Transmit Off)

^S

20

14

DC4

Device Control 4(設備控制4)

^T

21

15

NAK

Negative Acknowledgement(拒絕接收/無響應)

^U

22

16

SYN

Synchronous Idle(同步空閑)

^V

23

17

ETB

End of Trans the Block(傳輸塊結束)

^W

24

18

CAN

Cancel(取消)

^X

25

19

EM

End of Medium(已到介質末端/介質存儲已滿)

^Y

26

1A

SUB

Substitute(替補/替換)

^Z

27

1B

ESC

e

Escape(溢出/逃離/取消)

[

28

1C

FS

File Separator(文件分割符)

29

1D

GS

Group Separator(分組符)

]

30

1E

RS

Record Separator(記錄分隔符)

^ (Shit + 6)

31

1F

US

Unit Separator(單元分隔符)

_ (Shift + -)

32

20

SP

White space

[Space] *

127

7F

DEL

Delete(刪除)

?*

注(*):

1.轉義字符:即在C語言中或其他地方如何表示。

2.用鍵盤輸入控制字符:其中,32是空格鍵,都不需要加Ctrl鍵,即可直接輸入。

3.127是Delete鍵,除了可以用鍵盤上的刪除鍵輸入,也可以用Ctrl+?輸入。

4.可以通過“Ctrl+對應按鍵”實現上述控制字符的輸入,你可能遇到的一些,比如:用Ctrl+V輸入SYNC,Ctrl+M輸入Enter(當然也可以直接用Enter鍵,但是在Windows下面,其可能會發送兩個字符:CR和LF),Ctrl+Q輸入XON,Ctrl+S輸入XOFF等等。

^

總結

以上是生活随笔為你收集整理的过滤ASCII码中的不可见字符, ASCII三部分, 各控制字符详解, 去^@,^M的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。