/*
* ProCompile.java *預處理要編譯的文件,刪除多餘的空白,注釋,換行,回車等
* Created on 2007年9月18日, 下午8:58 */ package javacompile; import java.io.*;
import java.util.regex.*;
import javax.swing.JOptionPane; /** * @com.junjian.sun public class PerCompile { File f = null;
String fileString = null;
Pattern p = null;
Matcher m = null;
String regex; //正則表達式 //初始化p
public PerCompile() {
regex ="(//.+)" + //(//.+) 對應單行注釋
//"|(/\\*(.+\\n)+\\*/)"+ // 想對應多行注釋... "|(\\r\\n)" + "|(\\n)"+//(\\r\\n)|(\\n)對應換行
"|(\\B\\s+)" ; // 空白符
String ss;
f = new File(new JOptionPane()
.showInputDialog("請輸入文件所在路徑~"));
try {
BufferedReader bf = new BufferedReader(new FileReader(f));
ss = bf.readLine()+"\n";
fileString = ss; //如果沒有這兩句,ss的開頭會有「null」
while((ss = bf.readLine())!= null){
fileString += ss+"\n"; bf.close();
} catch (IOException ex) {
ex.printStackTrace(); p = Pattern.compile(regex);
m = p.matcher(fileString); //執行替換所有多餘空行,空白符,注釋
void Dels(){
System.out.println("before: "+fileString);
if(m.find()) System.out.println("find!!");
System.out.println(m.replaceAll("")); } }
-
『貳』 初學c語言時,輸入程序後運行,是執行還是預編譯預編譯是什麼為什麼最開始要有#include如
預編譯是把一個工程中較穩定的代碼預先編譯好放在一個文件里.這些預先編譯好的代碼可以是任何的C/C++代碼。而輸入程序後的運行,只是將代碼編譯成了obj(object)文件,所有obj文件經鏈接(link)成為可執行文件。而你說的執行,應該就是點擊最後生成的.exe文件了。開始要有的#include,是表明要包含的頭文件,或者其它的保存的代碼文件。只有這樣,你才可以引用到那個文件中的代碼,來供目前的文件來使用。
至於你說的什麼大型游戲的編程,應該也是這樣的一套,因為C語言就是上述生成文件的套路。游戲的編程,初學的話可以建議看《游戲編程入門》( 美 哈本),這本書基於windows平台,是為幾乎沒有游戲開發經驗的初學者寫的,循序漸進,從2D講到3D 的一些基本技術,其中的例子也非常經典,看完書基本就可以做出不錯的2D 游戲了,也有了一定的3D基礎了,之後再看一些深入的書籍像《Windows游戲編程大師技巧》。
『叄』 郵編的正則表達式
代碼如下:
package TestRegex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test01 {
/**
* 郵政編碼正則:"^[1-9]\d{5}$"
* ^:正則開始符
* $:正則結束符
* [1-9]:范圍為1-9
* :轉移字元
* d:數字【0-9】
* X{n}:恰好n次:注意從0開始
*/
public static void main(String[] args) {
//定義正則
String str= "^[1-9]\d{5}$";
//正確的郵件編碼
String s = "471400";
//錯誤郵政編碼
String s2 ="4560200";
/**
* Pattern為模式類型,
* compile(正則)方法預編譯正則,
* 得到一個Matcher對象
*/
Pattern p =Pattern.compile(str);
//Pattern中的matcher()方法傳入要匹配的字元串與正則進行匹配i
Matcher m=p.matcher(s);
Matcher m2=p.matcher(s2);
//Matcher類中的matches()方法判斷是否匹配成功
boolean bo= m.matches();
boolean bo2= m2.matches();
//輸出匹配結果:true為成功,false為失敗
System.out.println(bo);
System.out.println(bo2);
}
}
(3)正則表達式為什麼要預編譯擴展閱讀
正則表達式簡單語法及常用正則表達式:
基本符號:
^ 表示匹配字元串的開始位置 (例外 用在中括弧中[ ] 時,可以理解為取反,表示不匹配括弧中字元串)
$ 表示匹配字元串的結束位置
* 表示匹配 零次到多次
+ 表示匹配 一次到多次 (至少有一次)
? 表示匹配零次或一次
. 表示匹配單個字元
| 表示為或者,兩項中取一項
( ) 小括弧表示匹配括弧中全部字元
[ ] 中括弧表示匹配括弧中一個字元 范圍描述 如[0-9 a-z A-Z]
{ } 大括弧用於限定匹配次數 如 {n}表示匹配n個字元 {n,}表示至少匹配n個字元 {n,m}表示至少n,最多m
轉義字元 如上基本符號匹配都需要轉義字元 如 * 表示匹配*號
w 表示英文字母和數字 W 非字母和數字
d 表示數字 D 非數字
常用的正則表達式:
匹配中文字元的正則表達式:[u4e00-u9fa5]
匹配雙位元組字元(包括漢字在內):[^x00-xff]
匹配空行的正則表達式: [s|]*
匹配HTML標記的正則表達式:/<(.*)>.*</1>|<(.*)/>/
匹配首尾空格的正則表達式:(^s*)|(s*$)
匹配IP地址的正則表達式:/(d+).(d+).(d+).(d+)/g//
匹配Email地址的正則表達式:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*
『肆』 編譯原理
C語言編譯過程詳解
C語言的編譯鏈接過程是要把我們編寫的一個C程序(源代碼)轉換成可以在硬體上運行的程序(可執行代碼),需要進行編譯和鏈接。編譯就是把文本形式源代碼翻譯為機器語言形式的目標文件的過程。鏈接是把目標文件、操作系統的啟動代碼和用到的庫文件進行組織形成最終生成可執行代碼的過程。過程圖解如下:
從圖上可以看到,整個代碼的編譯過程分為編譯和鏈接兩個過程,編譯對應圖中的大括弧括起的部分,其餘則為鏈接過程。
一、編譯過程
編譯過程又可以分成兩個階段:編譯和匯編。
1、編譯
編譯是讀取源程序(字元流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,源文件的編譯過程包含兩個主要階段:
第一個階段是預處理階段,在正式的編譯階段之前進行。預處理階段將根據已放置在文件中的預處理指令來修改源文件的內容。如#include指令就是一個預處理指令,它把頭文件的內容添加到.cpp文件中。這個在編譯之前修改源文件的方式提供了很大的靈活性,以適應不同的計算機和操作系統環境的限制。一個環境需要的代碼跟另一個環境所需的代碼可能有所不同,因為可用的硬體或操作系統是不同的。在許多情況下,可以把用於不同環境的代碼放在同一個文件中,再在預處理階段修改代碼,使之適應當前的環境。
主要是以下幾方面的處理:
(1)宏定義指令,如 #define a b。
對於這種偽指令,預編譯所要做的是將程序中的所有a用b替換,但作為字元串常量的 a則不被替換。還有 #undef,則將取消對某個宏的定義,使以後該串的出現不再被替換。
(2)條件編譯指令,如#ifdef,#ifndef,#else,#elif,#endif等。
這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序對哪些代碼進行處理。預編譯程序將根據有關的文件,將那些不必要的代碼過濾掉
(3) 頭文件包含指令,如#include "FileName"或者#include <FileName>等。
在頭文件中一般用偽指令#define定義了大量的宏(最常見的是字元常量),同時包含有各種外部符號的聲明。採用頭文件的目的主要是為了使某些定義可以供多個不同的C源程序使用。因為在需要用到這些定義的C源程序中,只需加上一條#include語句即可,而不必再在此文件中將這些定義重復一遍。預編譯程序將把頭文件中的定義統統都加入到它所產生的輸出文件中,以供編譯程序對之進行處理。包含到C源程序中的頭文件可以是系統提供的,這些頭文件一般被放在/usr/include目錄下。在程序中#include它們要使用尖括弧(<>)。另外開發人員也可以定義自己的頭文件,這些文件一般與C源程序放在同一目錄下,此時在#include中要用雙引號("")。
(4)特殊符號,預編譯程序可以識別一些特殊的符號。
例如在源程序中出現的LINE標識將被解釋為當前行號(十進制數),FILE則被解釋為當前被編譯的C源程序的名稱。預編譯程序對於在源程序中出現的這些串將用合適的值進行替換。
預編譯程序所完成的基本上是對源程序的「替代」工作。經過此種替代,生成一個沒有宏定義、沒有條件編譯指令、沒有特殊符號的輸出文件。這個文件的含義同沒有經過預處理的源文件是相同的,但內容有所不同。下一步,此輸出文件將作為編譯程序的輸出而被翻譯成為機器指令。
第二個階段編譯、優化階段。經過預編譯得到的輸出文件中,只有常量;如數字、字元串、變數的定義,以及C語言的關鍵字,如main,if,else,for,while,{,}, +,-,*,\等等。
編譯程序所要作得工作就是通過詞法分析和語法分析,在確認所有的指令都符合語法規則之後,將其翻譯成等價的中間代碼表示或匯編代碼。
優化處理是編譯系統中一項比較艱深的技術。它涉及到的問題不僅同編譯技術本身有關,而且同機器的硬體環境也有很大的關系。優化一部分是對中間代碼的優化。這種優化不依賴於具體的計算機。另一種優化則主要針對目標代碼的生成而進行的。
對於前一種優化,主要的工作是刪除公共表達式、循環優化(代碼外提、強度削弱、變換循環控制條件、已知量的合並等)、復寫傳播,以及無用賦值的刪除,等等。
後一種類型的優化同機器的硬體結構密切相關,最主要的是考慮是如何充分利用機器的各個硬體寄存器存放的有關變數的值,以減少對於內存的訪問次數。另外,如何根據機器硬體執行指令的特點(如流水線、RISC、CISC、VLIW等)而對指令進行一些調整使目標代碼比較短,執行的效率比較高,也是一個重要的研究課題。
2、匯編
匯編實際上指把匯編語言代碼翻譯成目標機器指令的過程。對於被翻譯系統處理的每一個C語言源程序,都將最終經過這一處理而得到相應的目標文件。目標文件中所存放的也就是與源程序等效的目標的機器語言代碼。目標文件由段組成。通常一個目標文件中至少有兩個段:
代碼段:該段中所包含的主要是程序的指令。該段一般是可讀和可執行的,但一般卻不可寫。
數據段:主要存放程序中要用到的各種全局變數或靜態的數據。一般數據段都是可讀,可寫,可執行的。
UNIX環境下主要有三種類型的目標文件:
(1)可重定位文件
其中包含有適合於其它目標文件鏈接來創建一個可執行的或者共享的目標文件的代碼和數據。
(2)共享的目標文件
這種文件存放了適合於在兩種上下文里鏈接的代碼和數據。
第一種是鏈接程序可把它與其它可重定位文件及共享的目標文件一起處理來創建另一個 目標文件;
第二種是動態鏈接程序將它與另一個可執行文件及其它的共享目標文件結合到一起,創建一個進程映象。
(3)可執行文件
它包含了一個可以被操作系統創建一個進程來執行之的文件。匯編程序生成的實際上是第一種類型的目標文件。對於後兩種還需要其他的一些處理方能得到,這個就是鏈接程序的工作了。
二、鏈接過程
由匯編程序生成的目標文件並不能立即就被執行,其中可能還有許多沒有解決的問題。
例如,某個源文件中的函數可能引用了另一個源文件中定義的某個符號(如變數或者函數調用等);在程序中可能調用了某個庫文件中的函數,等等。所有的這些問題,都需要經鏈接程序的處理方能得以解決。
鏈接程序的主要工作就是將有關的目標文件彼此相連接,也即將在一個文件中引用的符號同該符號在另外一個文件中的定義連接起來,使得所有的這些目標文件成為一個能夠被操作系統裝入執行的統一整體。
根據開發人員指定的同庫函數的鏈接方式的不同,鏈接處理可分為兩種:
(1)靜態鏈接
在這種鏈接方式下,函數的代碼將從其所在地靜態鏈接庫中被拷貝到最終的可執行程序中。這樣該程序在被執行時這些代碼將被裝入到該進程的虛擬地址空間中。靜態鏈接庫實際上是一個目標文件的集合,其中的每個文件含有庫中的一個或者一組相關函數的代碼。
(2) 動態鏈接
在此種方式下,函數的代碼被放到稱作是動態鏈接庫或共享對象的某個目標文件中。鏈接程序此時所作的只是在最終的可執行程序中記錄下共享對象的名字以及其它少量的登記信息。在此可執行文件被執行時,動態鏈接庫的全部內容將被映射到運行時相應進程的虛地址空間。動態鏈接程序將根據可執行程序中記錄的信息找到相應的函數代碼。
對於可執行文件中的函數調用,可分別採用動態鏈接或靜態鏈接的方法。使用動態鏈接能夠使最終的可執行文件比較短小,並且當共享對象被多個進程使用時能節約一些內存,因為在內存中只需要保存一份此共享對象的代碼。但並不是使用動態鏈接就一定比使用靜態鏈接要優越。在某些情況下動態鏈接可能帶來一些性能上損害。
我們在linux使用的gcc編譯器便是把以上的幾個過程進行捆綁,使用戶只使用一次命令就把編譯工作完成,這的確方便了編譯工作,但對於初學者了解編譯過程就很不利了,下圖便是gcc代理的編譯過程:
從上圖可以看到:
預編譯
將.c 文件轉化成 .i文件
使用的gcc命令是:gcc –E
對應於預處理命令cpp
編譯
將.c/.h文件轉換成.s文件
使用的gcc命令是:gcc –S
對應於編譯命令 cc –S
匯編
將.s 文件轉化成 .o文件
使用的gcc 命令是:gcc –c
對應於匯編命令是 as
鏈接
將.o文件轉化成可執行程序
使用的gcc 命令是: gcc
對應於鏈接命令是 ld
總結起來編譯過程就上面的四個過程:預編譯、編譯、匯編、鏈接。了解這四個過程中所做的工作,對我們理解頭文件、庫等的工作過程是有幫助的,而且清楚的了解編譯鏈接過程還對我們在編程時定位錯誤,以及編程時盡量調動編譯器的檢測錯誤會有很大的幫助的。
是否可以解決您的問題?
『伍』 正則化 到底指什麼
正則化是為了使用正則表達式用以在海量數據中迅速查找匹配的數據方法。
『陸』 為什麼C語言中使用正則表達式時要先對其進行編譯
這個跟你用的正則表達式庫有關,要求編譯階段確定正則表達式的運行會快一些。 也有可以運行時編譯的,那個要慢一些
boost中帶有3個正則表達式庫,靜態和動態的都有,需要的話可以查一下怎麼用
『柒』 C/C++ 的預編譯原理是什麼為什麼要用預編譯
為了防止程序在實際應用當中出現錯誤
『捌』 驗證一個電話號碼,用正則表達式效率高還是自己寫邏輯效率高
一、使用正則表達式:
首先你需要把正則表達式正確的寫出來,如果只是網上搜的,那麼你不能確定你搜到的正則表達式是完全正確的;
如果是團隊合作,正則表達式可能會讓別人產生疑惑;
在java中,正則表達式需要先進行預編譯,否則執行效率不如直接使用邏輯代碼高
『玖』 VC66安裝BOOST的正則表達式庫和簡單使用,最好有圖文,分數不是問題
在WindowsXP下 VC6.0 編譯安裝Boost庫
基本思路:
一、需要什麼庫:boost有些庫是不用安裝的,即直接#include <>包含頭文件庫就行了,但是有些很有用的庫(thread-線程,regex-正則)需要根據不同的系統做不同的調整,所以必須編譯(即如果你要使用例如正則表達式類的話就需要編譯Boost庫了)。
二、如何編譯:
1、首先,生成bjam.exe。找到那個boostStrap.bat的東西,然後在CMD控制台下運行它,它會生成bjam.exe(類似c++的make,編譯.jam用)
2、然後就可以通過bjam來編譯boost庫了,在命令行下輸入bjam --help看選項。
如果嫌麻煩,可以一次將boost庫需要編譯的全部編譯了,bjam --build-type=complete,生成庫全在stage目錄下。■
可按照上述基本思路去解決。
(據說c6.0不支持目前比較新版本,下面以一些較舊的版本為例)
下面是參考步驟:
在安裝成功之前,我嘗試了許多版本,如1.40,其他的安裝了1.39,1.38,1.37,1.35都嘗試安裝過,但是都沒有成功。這里中原 因限於個人知識水平暫無法深究,但我以為可能是vc6.0無法支持高版本所致。於是我嘗試安裝1.34版本,終於解決安裝問題,由於只想使用其中的正則庫,文內將只以該文件編譯作為實例,其他的可以相同操作。
1、到Boost官方網站可以下載Boost的所有歷史版本,這里我下載的是1.341版。
2、將Boost壓縮包解壓到C:\Boost下。
3、將vc安裝目錄下\Microsoft Visual Studio\VC98\Bin 找到名為VCVARS32.BAT的批處理文件,並將其拷貝到C:\Boost\libs\regex\build目錄下。
4、cmd進入到C:\boost\libs\regex\build目錄下,執行VCVARS32.BAT(目的是使編譯文件命令nmake可用,否則 將提示nmake既不是內部也不是外部命令)後,敲入:nmake -f vc6.mak對其進行編譯,
5、數分鍾後,待編譯完成後,在C:\boost\libs\regex\build目錄下將產生名為vc的文件夾。我們將vc文件夾下的lib文件和 dll文件全部拷貝,在vc安裝目錄下xxx \Microsoft Visual Studio\VC98\下新建文件夾,名稱自定如BoostRegx,將lib和dll文件放入該文件夾中。
6、打開vc6.0選擇「Tools->Options->Directories->Include files,加入包含文件路徑"C:\BOOST"
7、選擇"Tools->Options->Directories->Library file" 編輯添加庫文件路徑 xxx\MICROSOFT VISUAL STUDIO\VC98\BOOSTREGX(這個是前面建立的文件夾BoostRegx的位置)。
8、編寫程序測試:
#include "stdafx.h"
#include <cstdlib>
#include <stdlib.h>
#include <boost/regex.hpp>
#include <string>
#include <iostream>
using namespace std;
using namespace boost;
regex expression("^select ([a-zA-Z]*) from ([a-zA-Z]*)");
int main(int argc, char* argv[])
{
std::string in;
cmatch what;
cout << "enter test string" << endl;
getline(cin,in);
if(regex_match(in.c_str(), what, expression))
{
for(int i=0;i<what.size();i++)
cout<<"str :"<<what.str()<<endl;
}
else
{
cout<<"Error Input"<<endl;
}
return 0;
}
9、由於Boost的Bug問題,寫段程序,頭文件,空間都引用正常,但編譯時編譯器卻告知連接錯誤 LNK1104: cannot open file "libboost_regex-vc6-sgd-1_34_1.lib",這樣可以通過修改Boost.Regx下相關lib文件的文件名改為 libboost_regex-vc6-sgd-1_34_1.lib(與錯誤里相同)即可。
10、再次vc里的編譯,ok了,0 error(s), 0 warning(s)。
我在VC6.0中裝了boost庫,測試程序的時候出現錯誤,說不能打開stdafx.h文件? 這個不是boost的問題,在項目->GUI屬性->c/c++->預編譯頭->創建/使用預編譯頭中選擇創建預編譯頭-確定即可。
《vc6.0環境下編譯Boost 1.34.1》:http://blog.sina.com.cn/s/blog_4bb397fa0100e12a.html
《vc6.0安裝boost1.34.1》:http://student.csdn.net/space.php?uid=119638&do=blog&id=36485
『拾』 正則表達式中/i,/g,/ig,/gi,/m的區別和含義
/i忽略大小寫的功能,是不能單獨使用的。
/g在全文中查找所出現的指定字元串。
/ig忽略大小寫在全文中查找指定字元串。
/gi/gi和/ig作用是一樣的,都是忽略大小寫在全文中查找指定字元串。
/m多行查找
正則表達式的通項: /pattern/flags 即(/模式/標記 )
構造器函數方法使用方法如下:
new RegExp("pattern"[, "flags"])(即new RegExp("模式"[,"標記"]))
pattern(模式)表示正則表達式的文本
flags(標記):如果指定此項,flags可以是下面值之一:
g: global match(全定匹配)i: ignore case(忽略大小寫)gi: both global match and ignore case(匹配所有可能的值,也忽略大小寫)
表達式建立同樣的正則表達式例如:
/ab+c/gi
(10)正則表達式為什麼要預編譯擴展閱讀:
特點
正則表達式的特點是:
1、靈活性、邏輯性和功能性非常強;
2、可以迅速地用極簡單的方式達到字元串的復雜控制。
3、對於剛接觸的人來說,比較晦澀難懂。
由於正則表達式主要應用對象是文本,因此它在各種文本編輯器場合都有應用,小到著名編輯器EditPlus,大到Microsoft Word、Visual Studio等大型編輯器,都可以使用正則表達式來處理文本內容。