[快递] GRUB4DOS-0.4.4正式版发布

发表于

等了好长时间GRUB4DOS-0.4.4正式版终于发布.

下载地址:

http://nufans.net/grub4dos/grub4dos-0.4.4.zip

http://nufans.net/grub4dos/grub4dos-0.4.4-src.zip

GRUB4DOS讨论或BUG报告(无需注册,可直接使用公用帐户PUBLIC登录)

http://bbs.znpc.net/forumdisplay.php?fid=4

该贴子使用Google文件的功能发布.以后就使用Google文件来写搏客了比较方便.^_^

ASP函数语法速查表

发表于

ASP函数语法速查表

































































































































































































































































































Abs(数值)绝对值。一个数字的绝对值是它的正值。空字符串 (null) 的绝对值,也是空字符串。未初始化的变数,其绝对为 0例子:ABS(-2000)

结果:2000
Array(以逗点分隔的数组元素)Array 函数传回数组元素的值。例子:

A=Array(1,2,3)

B=A(2)

结果: 2

说明:变量B为A数组的第二个元素的值。
Asc(字符串)将字符串的第一字母转换成 ANSI(美国国家标准符号)字码。例子:Asc("Internet")

结果:73

说明:显示第一字母 I 的 ANSI 字码。
CBool(表达式)转换成布尔逻辑值变量型态(True 或False)例子:CBool(1+2)

结果:True
CDate(日期表达式)换成日期变量型态。可先使用 IsDate 函数判断是否可以转换成日 期。例子: CDate (now( )+2)

结果:2000/5/28 10:30:59
CDbl(表达式)转换成DOUBLE变量型态。
Chr(ANSI 字码)将ASCII 字码转换成字符。例子: Chr(72)

结果: H
CInt(表达式)转换成整数变量型态。例子: CInt (“3.12”)

结果: 3
CLng(表达式)转换成LONG 变量型态。
CSng(表达式)转换成SINGLE 变量型态。
CStr(表达式)转换成字符串变量型态。
Date()传回系统的日期。例子: Date

结果: 2000/5/13
DateAdd(I , N , D)将一个日期加上一段期间后的日期。 I :设定一个日期( Date)所加上的一段期间的单位。譬如 interval=”d” 表示 N的单位为日。 I的设定值如下:

yyyy Year 年

q Quarter 季

m Month 月

d Day 日

w Weekday 星期

h Hour 时

n Minute 分

s Second 秒

N :数值表达式,设定一个日期所加上的一段期间,可为正值或负值,正值表示加(结果为 >date 以后的日期),负值表示减(结果为 >date 以前的日期)。

D :待加减的日期。
例子: DateAdd(“m” , 1 , “31-Jan-98”)

结果: 28-Feb-98

说明:将日期 31-Jan-98 加上一个月,结果为 28-Feb-98 而非 31-Fe-98 。

例子: DateAdd(“d” , 20 , “30-Jan-99”)

结果: 1999/2/9

说明:将一个日期 30-Jan-99 加上 20 天后的日期。
DateDiff (I , D1 , D2[,FW[,FY]])计算两个日期之间的期间。

I :设定两个日期之间的期间计算之单位。譬如 >I=”m” 表示计算的单位为月。 >I 的设定值如:

yyyy > Year 年

q Quarter 季

m Month 月

d Day 日

w Weekday 星期

h Hour 时

m Minute 分

s Second 秒

D1 ,D2:计算期间的两个日期表达式,若 >date1 较早,则两个日期之间的期间结果为正值;若 >date2 较早, 则结果为负值。

FW :设定每周第一天为星期几, 若未设定表示为星期天。 >FW 的设定值如下:

0 使用 >API 的设定值。

1 星期天

2 星期一

3 星期二

4 星期三

5 星期四

6 星期五

7 星期六

FY :设定一年的第一周, 若未设定则表示一月一日那一周为一年的第一周。 >FY 的设定值如下:

0 使用 >API 的设定值。

1 一月一日那一周为一年的第一周

2 至少包括四天的第一周为一年的第一周

3 包括七天的第一周为一年的第一周
例子: DateDiff (“d”,”25-Mar-99 “,”30-Jun-99 “)

结果: 97

说明:显示两个日期之间的期间为 97 天。
DatePart (I,D,[,FW[,FY]])传回一个日期的之部份。

>I :设定传回那一部份。譬如 >I=”d” 表示传回 部份为日。 >I 的设定值如下:

yyyy Year 年

q Quarter 季

m Month 月

d Day 日

w Weekday 星期

h Hour 时

m Minute 分

s Second 秒

D :待计算的日期。

>FW :设定每周第一天为星期几, 若未设定则表示为星期天。 >FW 的设定值如下:

0 使用 >API 的设定值。

1 星期天

2 星期一>3 星期二

4 星期三

5 星期四

6 星期五

7 星期六

FY :设定一年的第一周, 若未设定则表示一月一日那一周为一年的第一周。 >FY 的设定值如下:

0 使用 >API 的设定值。

1 一月一日那一周为一年的第一周

2 至少包括四天的第一周为一年的第一周

3 包括七天的第一周为一年的第一周
例子: DatePart (“m”,”25-Mar-99 “)

结果: 3

说明:显示传回一个日期 的月部份。
Dateserial (year,month,day)转换(year,month,day) 成日期变量型态。例子: DateSerial (99,10,1)

结果: 1999/10/1
DateValue ( 日期的字符串或表达式 )转换成日期变量型态,日期从 January 1,100 到 December 31,9999 。格式为 month,day,and year 或 month/day/year 。譬如: December 30,1999 、 Dec 30,1999 、 12/30/1999 、 12/30/99例子: DateValue (“January 1,2002 “)

结果: 2002/1/1
Day( 日期的字符串或表达式 )传回日期的「日」部份。例子: Day(“ 12/1/1999 “)

结果: 1
Fix( 表达式 )转换字符串成整数数字型态。与 Int 函数相同。若为 null 时传回 null 。

Int (number) 与 Fix(number) 的差别在负数。如 Int (-5.6)=-6 , Fix(-5.6)=-5 。
例子: Fix(5.6)

结果: 5
Hex( 表达式 )传回数值的十六进制值。若表达式为 null 时 Hex( 表达式 )=null ,若表达式 =Empty 时 Hex( 表达式 )=0 。 16 进位可以加「 &H 」表示,譬如 16 进位 &H10 表示十进制的 16 。例子: Hex(30)

结果: 1E
Hour( 时间的字符串或表达式 )传回时间的「小时」部份。例子: Hour(“12:30:54 “)

结果: 12
InStr ([start,]string1,string2[,compare]) 将一 个 字符串由左 而右与另一个比较,传回第一个相同的位置。

start 为从第几个字比较起,若省略 start 则从第一个字比较起, string1 为待寻找的字符串表达式, string2 为 待比较的字符串表达式, compare 为比较的方法, compare=0 表二进制比较法, compare=1 表文字比较法,若省略 compare 则为预设的二进制比较法。
例子: InStr(“abc123def123”,”12”)

结果: 4
InstrRev ([start,]string1,string2[,compare])将一 个 字符串 由右而左与另一个比较,传回第一个相同的位置。

start 为从第几个字比较起,若省略 start 则从第一个字比较起, string1 为待寻找的字符串表达式, string2 为 待比较的字符串表达式, compare 为比较的方法, compare=0 表二进制比较法, compare=1 表文字比较法,若省略 compare 则为预设的二进制比较法。
例子: InstrRev (“abc123def123”,”12”)

结果: 10
Int ( 表达式 )传回一个数值的整数部份。与 Fix 函数相同。例子: Int (5.6)

结果: 5
IsArray ( 变数 )测试变量是 (True) 否 (False) 是一个数组。例子: IsArray (3)

结果: False

说明:不是一个数组。
IsDate ( 日期或字符串的表达式 )是否可以转换成日期。日期从 January 1,100 A.D. 到 December 31,9999 A.D 。例子: IsDate (“December 31,1999 “)

结果: True

说明:可以转换成日期。
IsEmpty ( 变数 )测试变量是 (True) 否 (False) 已经被初始化例子: IsEmpty (a)

结果: True
IsNull ( 变数 )测试变数是 (True) 否 (False) 不是有效的数据。例子: IsNull (“”)

结果: False

说明:是有效的数据。
IsNumeric ( 表达式 )是 (True) 否 (False) 是数字。例子: IsNumeric (“abc123”)

结果: False

说明:不是数字。
LCase ( 字符串表达式 ) top转换字符串成小写。将大写字母的部份转换成小写。字符串其余的部份不变。例子: LCase (“ABC123”)

结果: abc123
Left( 字符串表达式 ,length)取字符串左边的几个字。 length 为取个字。 Len 函数可得知字符串的长度。例子: Left(“ABC123”,3)

结果: ABC
Len( 字符串表达式 变量 )取得字符串的长度。例子: Len(“ABC123”)

结果: 6
LTrim ( 字符串表达式 )除去字符串左边的空白字。 RTrim 除去字符串右边的空白字, Trim 函数除去字符串左右两边的空白字。例子: LTrim (“456+” abc “)

结果: 456abc123
Mid( 字符串表达式 ,start[,length]) 取字符串中的几个字。 start 为从第几个 字取起, length 为取几个字, 若略 length 则从 start 取到最右底。由Len 函数可得知字符串的长度。例子: Mid(“abc123”,2,3)

结果: c12
Minute( 日期的字符串或表达式 )传回时间的「分钟」部份。例子: Minute(“12:30:54”)

结果:30
Month(日期的字符串或表达式)传回日期的「月」部份。例子:Month(“12/1/2001”)

结果:12
MonthName(month[,abbreviate])传回月的名称。

month :待传回月名称的数字 1~12 。譬如, 1 代表一月, 7 代表七月。

abbreviate: 是 (True) 否 (False) 为缩写,譬如 March ,缩写为 Mar 。默认值为 False 。中文的月名称无缩写。
例子: MonthName (7)

结果:七月
Now()传回系统的日期时间。例子: Now()

结果: 2001/12/30 10:35:59 AM
Oct()传回数值的八进位值。八进位可以加「 &O 」表示,譬如八进位 &O10 表示十进制的 8 。例子: Oct(10)

结果: 12
Replace( 字符串表达式,findnreplacewith[,start[,count[,compare]]]) 将一个字符串取代 部份字。寻找待取代的原字符串 (find) , 若找到则被取代为新字符串 (replacewith) 。

find :待寻找取代的原字符串。

replacewith :取代后的字。

start :从第几个字开始寻找取代, 若未设定则由第一个字开始寻找。

count :取代的次数。 若未设定则所有寻找到的字符串取代字符 串全部被取代。

compare :寻找比较的方法, compare=0 表示二进制比较法, compare=1 表文字比较法, compare =2 表根据比较的 数据型态而定,若省略 compare 则为预设的二进制比较法。
例子: Replace(“ABCD123ABC”,”AB”,”ab”)

结果: abCD123abC
Right( 字符串表达式 ,length)取字符串右边的几个字, length 为取几个字。 Len 函数可得知字符串的长度。例子: Right(“ABC123”,3)

结果: 123
Rnd [(number)]0~1 的 随机随机数值。 number 是任何有效的数值表达式。若 number 小于 0 表示每次得到相同的 随机随机数值。 number 大于 0 或未提供时表示依序得到下一个 随机随机数值。 >number=0 表示得到最近产生的 随机随机数值。为了避免得到相同的随机随机数顺序,可以于 Rnd 函数前加 Randomize 。例子: Rnd

结果: 0.498498
Round( 数值表达式 [,D])四舍五入。

D :为四舍五入到第几位小数,若省略则四舍五入到整数。
例子: Round(30635,1)

结果: 3.6
RTrim ( 字符串表达式 )除去字符串右边的空白字。 LTrim 除去字符串左边的空白字, Trim 函数除去字符串左右两边的空白字。例子: RTrim (“abc123 “)+”456”

结果: abc123456
Second( 时间的字符串或表达式 )传回时间的「秒」部份。例子:Second(“12:30:54”)

结果:54
Space( 重复次数 )得到重复相同的空白字符串。例子: A”+Space (5)+”B

结果: A B

说明: A 和 B 中间加入五个空白字。
String( 重复次数,待重复的字 )得到重复相同的字符串。例子: String(5,71)

结果: GGGGG
StrReverse (String(10,71))将一个字符串顺序颠倒。例子: StrReverse (“ABC”)

结果: CBA
Time()传回系统的时间。例子: Time

结果: 10:35:59 PM
TimeSerial (hour,minute,second)转换指定的 ( hour,minute,second) 成时间 变量型态。例子: TimeSerial (10,31,59)

结果: 10:31:59
TimeValue ( 日期的字符串或表达式 )转换 成时间变量型态。日期的字符串或表达式从 0:00:00(12:00:00 A.M.) 到 23:59:59(11:59:59 P.M.) 。例子: TimeValue (“ 11:59:59 “)

结果: 11:59:59
Trim( 字符串表达式 )除去字符串左右两边的空白字。例子: Trim(“ abc123 “)

结果: abc123
UCase ()转换字符串成大写。将小写字母的部份转换成大写,字符串其余部份不变。例子: UCase (“abc123”)

结果: ABC123
VarType ( 变数 )传回一个变量类型。与 TypeName 函数相同, VarType 传回变量类型的代码, TypeName 传回变量类型的名称。例子: VarType ( “I love you!”)

结果: 8
Weekday( 日期表达式 ,[FW]) 传回星期几的数字。

FW :设定一周的第一天是星期几。若 省略则表 1( 星期日 ) 。

Firstdayfweek 设定值为: 1( 星期日 ),2( 星期一 ),3( 星期二 ),4( 星期三 ),5( 星期四 ),6( 星期五 ),7( 星期六 ) 。
例子: Weekday(“ 1/1/2000”)

结果: 7
WeekDayName (W,A,FW)传回星期几的名称。

W :是 (True) 否 (False) 为缩写。譬如 March ,缩写为 Mar 。预设为 False 。中文的星期几名称无缩写。

FW :设定一周的第一天是星期几。 若省略表 1( 星期日 ) 。设定待传回星期几的名称,为一周中的第几天。

A : 1( 星期日 ),2( 星期一 ),3( 星期二 ),4( 星期三 ),5( 星期四 ),6( 星期五 ),7( 星期六 ) 。
例子: WeekDayName (“1/1/2000”)

结果:星期六
Year()传回日期的「年」部份。例子: Year(“ 12/1/2000 “)

结果: 2000

[原创] 无限扩展,多功能PE_更新与下载(2009-05-01)最终版

发表于

可以点击链接直接下载,或者进入网络硬盘下载。共享密码是:chenall

外置驱动使用说明.txt

请先读我.txt

更新历史.txt

2009-05-01 修正版ISO下载[2009-05-03]

http://chenall.liondrive.com/MicroPE/MicroPE.rar?action=download/download

如果没有看到请

2009-05-01成品ISO下载测试

http://dl.getdropbox.com/u/835279/MicroPE.ISO

基本上不会再更新,除非有重大问题.

目前自用,一般也就更新一下驱动或解决一些小BUG,优化之类的.

目前本PE已经传到了我的live mesh网盘,和我的电脑上进行同步.如果有使用live mesh并且需要得到最新版的PE的朋友可以留下live id.

我将把这个共享给你,就可以同步更新了.关于live mesh的资料请上网查找.

2014-01-21 注: 本PE已经早就不更新了,本文只保留作为研究的记录.

类似的PE推荐使用 pseudo0PE

本PE特色:

  1. 首创支持直接使用ISO启动,而且不影响任何功能. 使用ISO启动可以自动找到ISO里面的外置程序
    需求: 启动ISO文件必须为 /BOOT/MICROPE.ISO
  2. 首创支持外置硬盘控制器(S&R&S)驱动.遇到新的主板进入PE后没有找到硬盘可以方便的添加驱动而不需要重新修改启动镜像内容.
  3. 首创支持多重启动,任意启动,想怎么启动都可以.启动加载的IMG只有15MB.
  4. 启动核心最小并且保持功能完整.启动后如果缺什么功能都可以通过外置程序来添加.
  5. 首创支持iSCSI启动,也是首个支持iSCSI客户端连接的XP PE
  6. 首创充许把核心IMG里面的文件直接解开放在U盘或硬盘上进行启动.(不建议使用)
  7. 外置程序模块化,傻瓜化添加,基本上只需复制粘贴就可以了.
  8. 本地/光盘/iSCSI/网络PXE等,随意启动.

2009-01-19 ,具体请看更新历史.txt

PE090115出现失误,请自行修改[PE定制]目录下的批处理把以下语句后面的Micrope.lst改为menu.lst

grubmenu.exe import boot\grldr boot\MicroPE.lst

2009-01-16

不再整个ISO文件上传,使用了可定制的方式上传所有需要的文件,加了一些说明.

可根据需要自己生成ISO文件.

其它请查看更新历史页面.

下载地址:

http://www.brsbox.com/chenall

PE090115.rar

这个版本已经支持ISCSI启动,只要手工内置SYSTEM.WIM和NET.WIM就可以了.

SYSTEM.WIM内置到WXPE\SYSTEM\SYSTEM.WIM

NET.WIM内置到WXPE\NET\NET.WIM.

说明书尚未添加ISCSI启动的资料,.有关ISCSI启动请查看无忧论坛相关贴子.

2009-01-08.

细微调整,整个ISO文件上传146MB.

[MicroPE.iso]

注意:

  1. 如果要解开ISO请使用IsoBuster否则解开的文件不完整.

  2. 硬盘控制器驱动直接使用了pseudo 的OPE 1230版本的驱动.

  3. 因为我是维护用的,内置RADMIN服务端,启动网络后会自动运行.方便进行远程控制.

  4. 此版核心支持ISCSI启动,

方法,把NET.WIM和SYSTEM.WIM内置到WINPE.IMG里面即可.

目录限制.内置NET.WIM放在WXPE\NET目录下.SYSTEM.WIM放在WXPE\SYSTEM目录下.否则无效.

然后在WINPE.IMG根目录下新建一个文件夹DRIVERS里面放网卡驱动.

2008-12-03.

由于我没有使用光盘测试而是直接用硬盘启动,所以一直没有发现一个问题.今天用光盘启动才发现.

当使用光盘启动时,驱动目录的设置可能会出错,造成驱动安装失败.

解决方法:

修改MINIPE\AUTORUN.INF文件

把以下语句修改一下即可.

ENVI $Drivers=%curdrv%\minipe\Drivers

改成如下.

ENVI $Drivers=%curdir%\Drivers

说明:虽然两句要表达的意思是一样的,但是用后面那一句通用性比较高..

因为%curdrv%无法识别\\?\cdrom0,所以失败.

2008-11-24.

  1. 添加了最新版的PECMD.EXE. 
  2. 更新了UNIATA驱动到最新版.
  3. 更新了启动文件GRLDR到最新版(调整了启动菜单MENU.LST)
  4. 内置了EXFAT文件系统驱动.

还有一些细微修改,其中某些文件参考了pseudo

【无忧首发】零体积全能可扩展PE(软盘装得下的PE,11.01)的版本进行修改.

2008-05-14

1.新版SCSI.IMG测试 带完整驱动。从根据以下贴子的资料整理

[4月12日]基于毛桃PE的SATA、RAID驱动补充优化1.3修正版(新内核测试4+新问题)

[待测]Intel、SIS、VIA、ULI/ALI、AMD、ATI、NV南桥磁盘驱动BETA版[5月13日]

2008-05-11

1.添加了极点中文输入法(带86五笔)精简版(用于PE).@1#FreeIme_.WIM 极点6.2CCF专版

2008-05-10

1.磁盘分区表医生 PTDD 使用了无忧玄天发表的汉化破解版,

http://bbs.wuyou.com/viewthread.php?tid=120397&page=77#pid1390729

2.PE定制包, 更新

GRLDR更新到05-07版,修改了HIDE.TXT内容(隐藏所有启动相关的文件,使得光盘上的文件在WINDOWS下看起来比较整洁)

修改了默认的菜单,

2008-05-05

1.SCSI.IMG测试,使用了新的检测方式.

2008-05-04

1.WINPE.IMG更新,自动挂载支持自动运行(挂载时运行,方便作一些前期设定文件WIM里面的+AutoRun.cmd)

2008-04-30

1.网络@net.wim更新.

1).支持启动网络后自动运行脚本(启动网络自动运行.cmd,可使用其它批处理或程序来生成,如果文件存在启动网络后会自动运行).

2).连接后在通知区域显示图标 by pseudo (http://bbs.wuyou.com/viewthread.php?tid=123874)

2.haneWIN DHCP升级到3.0.20版

3.DiskGenius更新为3.0.418 b2版

2008-04-15

外置更新

1.外置驱动SCSI.IMG更新,使用了新版的GRUB.EXE.修改了里面的一些驱动.

注:目前的SCSI.IMG加载驱动时,在有些主板上会检测不到。暂时先用着,下次更新将使用新的检测方法。

2.外置SYSTEM.WIM更新:修改了SYSTEM_.CMD批处理的语法错误.

2008-04-14

WINPE.IMG更新

1.替换了XP_TOOLS.WIM为新版.

2.修改了PELOGON.EXE的托盘菜单.直接使用以下贴子文件替换(另修改了热键按CTRL+ALT+A的刷新率为60,原文件没有改这个)

原贴:http://bbs.wuyou.com/viewthread.php?tid=121168&page=48#pid1373269

3.加入了VIA PCI潜伏期补丁

原贴:http://bbs.wuyou.com/viewthread.php?tid=122156&page=2#pid1358101

4.批处理Bug修正.

2008-03-24

1.修改了PE定制包里面的MENU.LST菜单,加上容错语句.由无忧yiyaxuan发现并解决问题

2008-03-21

1.替换了SCSI.IMG里面的GRUB.EXE为最新版,解决有些电脑启动失败的问题.

2.修改了MENU.LST启动菜单,使用1,2都支持外置的OEM_SCSI.IMG驱动.

3.把WINPE.IMG分别压缩成WINPE.IM_和WINPE.GZ两个文件.

2008-03-19

1.替换内置的RAMDISK为IMDISK.在使用复制SYSTEM.WIM到内存盘时,所需的时间更少

2.加了一个外置SCSI驱动工具(目录SCSI),使用方法内详

功能:可以把某个SCSI驱动由TXTSETUP.OEM格式转为txtsetup.sif格式,并生成对应的驱动信息文件(可直接复制添加到SCSI.MAP中)

注:此为方便添加外置SCSI驱动而作,生成的文件不保证完全可靠.完成后请自行检查.

2008-03-18

1.修改了WINPE.IMG,加入了免按F6自动加载S&R&S驱动的支持.

2.修改了启动菜单,使之支持以上方法的外置SCSI驱动(镜像路径为/OEM_SCSI.IMG,有存在的话就自动加载驱动)

用途:

只需制作一个文件名为OEM_SCSI.IMG(可以用GZIP压缩),放到U盘或硬盘的根目录(只要GRUB4DOS可以找到的都可以)

启动PE时就会自动加载这个里面的驱动. 驱动文件和传统的按F6加载的软盘的文件一样.

2008-03-17

1.为外置SCSI.IMG加入了ryvius提供的Intel 和 Nvidia 驱动(本人未测试)

具体请看由无忧ryvius发表的贴子

NVIDIA nForce SATA RAID/AHCI解决方案

http://bbs.wuyou.com/viewthread.php?tid=11273

Intel芯片组IDE、RAID/AHCI解决方案

http://bbs.wuyou.com/viewthread.php?tid=116417

2008-03-16

*修改了小错误,还是谢谢pz的提醒

*根据pseudo提供的资料,在IMG里面加入PORTCLS.SYS文件,解决声音问题.顺便修改了一下XP资源利用.

*添加了一些注释,以方便他人YY.

*为了防止恶意修改启动脚本造成启动失败,在AUTORUNS_.CMD内加了简单的校验

修改了这个文件就会进不了PE,启动到CMD后就直接重启.

当然了懂得批处理的人要修改自然是很简单的(知道了也请不要张扬).

如非特殊需要,不建议修改WINPE.IMG的内容,一般来说都可以通过外置的方式来解决.

.不带其它外置,请自备.以后会提供专门的外置程序下载.

2008-03-14,更新

*.修改了GRUB启动菜单,只保留一个RAMDISK启动菜单,默认不显示菜单.5秒后自动使用自动检测SCSI驱动的菜单.

*.SCSI.IMG的GRUB菜单也有相应的修改,同时GRUB换上了新版的0314版. SYSTEM.WIM改了一下,强制开启FBWF和一些文本错误.

*.加入了之前外置工具,完整上传,需要的可下载测试,在将来一段时间内可能不会再更新了.

2008-03-13,更新

*.加入了XP资源利用的NV网卡补丁,由pseudo提供(无忧)

*.再修改了一个自启动的批处理,影响不大

2008-03-12,更新

*去掉RAMDISK的启动菜单,使用单IMG文件来启动.

*修改IMG的启动批处理,之前的版本还是不可以直接使用非RAMDISK来启动(有问题)

*修改SCSI.IMG,改正了一些可能出现的错误.

*不论如何强制开启FBWF

*IMG改为28MB,虚拟机测试80MB可进桌面(用WDSYS)

以下根据pz(无忧)的建议修改.

*修改了一些界面显示的文本错误,

*启动时自动关闭小键盘(方便本本用户).

*改了一些文本错误(无优==>无忧)谢谢qdaijchf(无忧)的提醒

发现我的错别字挺多的,呵呵一直都没有注意这些细节.以后还是仔细一点好.

08-03-11,修改

*修改默认菜单为第5条(自动加载适配的SCSI/RAID驱动)

*修改第5条菜单的内容,如果找不到SCSI.IMG就自动转到第4菜单执行

*修改SCSI.IMG的GRUB启动菜单,启动之前删除多余的映射防止启动蓝屏.

*修改IMG的Autoruns_.cmd批处理,使得适合使用非RAMDISK启动(之前的版本,如果直接用非RAMDISK启动会删除一些启动文件,下次就不能启动了.)

*注:若修改了IMG,这个IMG的卷标必须为MICROPE,否则启动时就不删除像TXTSETUP.SI?之类的文件.(原因同上).

若要使用非RAMDISK启动,则该磁盘磁标不能为MICROPE,否则启动一次后就不能再使用了(因为启动必须的文件会被删).

08-03-10,修改

新增菜单0

功能:和第2个菜单一样,但是不加载无盘天使驱动(测试,因为有些加了会蓝屏)

其它:该项不能使用下面的第二种方法来启动,因为没有带天使驱动.只是作为备用菜单

删除了DRIVERS目录下的一些文件(参考无忧uepon 20Mb的Vista美化PE).

相关贴子:http://bbs.wuyou.com/viewthread.php?tid=121708&extra=page%3D2

[grub4dos]在GRLDR中内置超过4KB菜单的方法

发表于

大家都知道GRLDR中的内置菜单不能超过4KB,如果超过就会被截断.

如果超过4KB的菜单想要内置怎么办呢?

之前有想过使用GZ压缩,可是内置菜单不支持GZ压缩的格式.

后来得知启动后内置菜单的位置在内存中是固定的0X800处.

所以就想了个折中的办法.在内置的菜单中加入GZ压缩的菜单文件.

原理我就不多说了,贴上代码.

使用方法,

把以下代码另存为批处理文件,把你的菜单文件用GZ压缩(压缩后不能超过3KB)

然后使用批处理加参数执行(或直接把压缩后的菜单文件拖放到批处理文件图标上)

再用GRUBMENU导入生成的menu.lst就可以了.

注意使用grubmenu导入时要加-r参数如下.

grubmenu -r import grldr menu.lst

@echo off
setlocal
cd /d "%~dp0"
if not exist "%~1" (
  echo.参数错误!!
  pause
  goto :eof
)
for %%i in (%1) do echo.configfile (md)5+7,%%~zi>menu.lst
for %%i in (menu.lst) do set /a ns=512-%%~zi
fsutil file createnew menu_ex.lst %ns%
copy /y /b menu.lst /b + menu_ex.lst /b + %1 /b
del menu_ex.lst
pause 15.

[GRUB4DOS] 利用WRITE命令写字符串到内存中

发表于

熟悉GRUB4DOS的都知道.

write 可以在内存中写入一个数值使用如下命令就可以了

write 0x60000 1

在内存地址0x60000中写入1.

如果想写入的是一个字符串呢?用上面的方法肯定行不通.

因为需要我想在内存固定位置中写入一个字符串,在另一个菜单中读取.之前考虑了使用dd命令,虽可以实现但不太方便.

后来突然想到write 只能对文件写入字符串

grub4dos中可以用(xx)xxxx+n的方式来表达一个文件.是不是可以使用这个来写入呢,后来的测试是成功的.

比如我要在内存0x60000中写入一个字符串/BOOT这时就可以使用以下命令来写入

write (md)0x300+1 /boot

其中:0x300*512=0x60000

[分享]超级解霸V9精简版(用来播放光蝶)

发表于

豪杰超级解霸V9 Vsita 增强版http://www.haojie.cn/


精简版功能.(压缩后只有2.5MB)

  1. 保留视频功能.
  2. 保留自动播放司服器
  3. 修正原版自动播放司服器不能正常使用的问题.
  4. 添加了V8版和3500版的皮肤(已修改过).(使用V9版皮肤可以点右下角的超级解霸字样进行切换皮肤).

精简版下载 新浪共享

附,皮肤截图




[转]正则表达式30分钟入门教程

发表于

正则表达式30分钟入门教程

版本:v2.33 (2013-1-10) 作者:deerchao 转载请注明来源

目录

跳过目录

  1. 本文目标
  2. 如何使用本教程
  3. 正则表达式到底是什么东西?
  4. 入门
  5. 测试正则表达式
  6. 元字符
  7. 字符转义
  8. 重复
  9. 字符类
  10. 分枝条件
  11. 反义
  12. 分组
  13. 后向引用
  14. 零宽断言
  15. 负向零宽断言
  16. 注释
  17. 贪婪与懒惰
  18. 处理选项
  19. 平衡组/递归匹配
  20. 还有些什么东西没提到
  21. 联系作者
  22. 网上的资源及本文参考文献
  23. 更新纪录

本文目标

30分钟内让你明白正则表达式是什么,并对它有一些基本的了解,让你可以在自己的程序或网页里使用它。

如何使用本教程

最重要的是——请给我30分钟,如果你没有使用正则表达式的经验,请不要试图在30内入门——除非你是超人 :)

别被下面那些复杂的表达式吓倒,只要跟着我一步一步来,你会发现正则表达式其实并没有想像中的那么困难。当然,如果你看完了这篇教程之后,发现自己明白了很多,却又几乎什么都记不得,那也是很正常的——我认为,没接触过正则表达式的人在看完这篇教程后,能把提到过的语法记住80%以上的可能性为零。这里只是让你明白基本的原理,以后你还需要多练习,多使用,才能熟练掌握正则表达式。

除了作为入门教程之外,本文还试图成为可以在日常工作中使用的正则表达式语法参考手册。就作者本人的经历来说,这个目标还是完成得不错的——你看,我自己也没能把所有的东西记下来,不是吗?

清除格式 文本格式约定:专业术语 元字符/语法格式 正则表达式 正则表达式中的一部分(用于分析) 对其进行匹配的源字符串 对正则表达式或其中一部分的说明

隐藏边注 本文右边有一些注释,主要是用来提供一些相关信息,或者给没有程序员背景的读者解释一些基本概念,通常可以忽略。

正则表达式到底是什么东西?

字符是计算机软件处理文字时最基本的单位,可能是字母,数字,标点符号,空格,换行符,汉字等等。字符串是0个或更多个字符的序列。文本也就是文字,字符串。说某个字符串匹配某个正则表达式,通常是指这个字符串里有一部分(或几部分分别)能满足表达式给出的条件。

在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。

很可能你使用过Windows/Dos下用于文件查找的通配符(wildcard),也就是*?。如果你想查找某个目录下的所有的Word文档的话,你会搜索*.doc。在这里,*会被解释成任意的字符串。和通配符类似,正则表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精确地描述你的需求——当然,代价就是更复杂——比如你可以编写一个正则表达式,用来查找所有以0开头,后面跟着2-3个数字,然后是一个连字号“-”,最后是7或8位数字的字符串(像010-123456780376-7654321)。

入门

学习正则表达式的最好方法是从例子开始,理解例子之后再自己对例子进行修改,实验。下面给出了不少简单的例子,并对它们作了详细的说明。

假设你在一篇英文小说里查找hi,你可以使用正则表达式hi

这几乎是最简单的正则表达式了,它可以精确匹配这样的字符串:由两个字符组成,前一个字符是h,后一个是i。通常,处理正则表达式的工具会提供一个忽略大小写的选项,如果选中了这个选项,它可以匹配hi,HI,Hi,hI这四种情况中的任意一种。

不幸的是,很多单词里包含hi这两个连续的字符,比如him,history,high等等。用hi来查找的话,这里边的hi也会被找出来。如果要精确地查找hi这个单词的话,我们应该使用\bhi\b

\b是正则表达式规定的一个特殊代码(好吧,某些人叫它元字符,metacharacter),代表着单词的开头或结尾,也就是单词的分界处。虽然通常英文的单词是由空格,标点符号或者换行来分隔的,但是\b并不匹配这些单词分隔字符中的任何一个,它只匹配一个位置

如果需要更精确的说法,\b匹配这样的位置:它的前一个字符和后一个字符不全是(一个是,一个不是或不存在)\w

假如你要找的是hi后面不远处跟着一个Lucy,你应该用\bhi\b.*\bLucy\b

这里,.是另一个元字符,匹配除了换行符以外的任意字符*同样是元字符,不过它代表的不是字符,也不是位置,而是数量——它指定*前边的内容可以连续重复使用任意次以使整个表达式得到匹配。因此,.*连在一起就意味着任意数量的不包含换行的字符。现在\bhi\b.*\bLucy\b的意思就很明显了:先是一个单词hi,然后是任意个任意字符(但不能是换行),最后是Lucy这个单词

换行符就是'\n',ASCII编码为10(十六进制0x0A)的字符。

如果同时使用其它元字符,我们就能构造出功能更强大的正则表达式。比如下面这个例子:

0\d\d-\d\d\d\d\d\d\d\d匹配这样的字符串:以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字(也就是中国的电话号码。当然,这个例子只能匹配区号为3位的情形)。

这里的\d是个新的元字符,匹配一位数字(0,或1,或2,或……)-不是元字符,只匹配它本身——连字符(或者减号,或者中横线,或者随你怎么称呼它)。

为了避免那么多烦人的重复,我们也可以这样写这个表达式:0\d{2}-\d{8}。这里\d后面的{2}({8})的意思是前面\d必须连续重复匹配2次(8次)

测试正则表达式

如果你不觉得正则表达式很难读写的话,要么你是一个天才,要么,你不是地球人。正则表达式的语法很令人头疼,即使对经常使用它的人来说也是如此。由于难于读写,容易出错,所以找一种工具对正则表达式进行测试是很有必要的。

不同的环境下正则表达式的一些细节是不相同的,本教程介绍的是微软 .Net Framework 4.0 下正则表达式的行为,所以,我向你推荐我编写的.Net下的工具 正则表达式测试器。请参考该页面的说明来安装和运行该软件。

下面是Regex Tester运行时的截图:

正则表达式测试器运行截图

元字符

现在你已经知道几个很有用的元字符了,如\b,.,*,还有\d.正则表达式里还有更多的元字符,比如\s匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等\w匹配字母或数字或下划线或汉字等

对中文/汉字的特殊处理是由.Net提供的正则表达式引擎支持的,其它环境下的具体情况请查看相关文档。

下面来看看更多的例子:

\ba\w*\b匹配以字母a开头的单词——先是某个单词开始处(\b),然后是字母a,然后是任意数量的字母或数字(\w*),最后是单词结束处(\b)

好吧,现在我们说说正则表达式里的单词是什么意思吧:就是不少于一个的连续的\w。不错,这与学习英文时要背的成千上万个同名的东西的确关系不大 :)

\d+匹配1个或更多连续的数字。这里的+是和*类似的元字符,不同的是*匹配重复任意次(可能是0次),而+则匹配重复1次或更多次

\b\w{6}\b 匹配刚好6个字符的单词

表1.常用的元字符
代码 说明
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束

正则表达式引擎通常会提供一个“测试指定的字符串是否匹配一个正则表达式”的方法,如JavaScript里的RegExp.test()方法或.NET里的Regex.IsMatch()方法。这里的匹配是指是字符串里有没有符合表达式规则的部分。如果不使用^$的话,对于\d{5,12}而言,使用这样的方法就只能保证字符串里包含5到12连续位数字,而不是整个字符串就是5到12位数字。

元字符^(和数字6在同一个键位上的符号)和$都匹配一个位置,这和\b有点类似。^匹配你要用来查找的字符串的开头,$匹配结尾。这两个代码在验证输入的内容时非常有用,比如一个网站如果要求你填写的QQ号必须为5位到12位数字时,可以使用:^\d{5,12}$

这里的{5,12}和前面介绍过的{2}是类似的,只不过{2}匹配只能不多不少重复2次{5,12}则是重复的次数不能少于5次,不能多于12次,否则都不匹配。

因为使用了^$,所以输入的整个字符串都要用来和\d{5,12}来匹配,也就是说整个输入必须是5到12个数字,因此如果输入的QQ号能匹配这个正则表达式的话,那就符合要求了。

和忽略大小写的选项类似,有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项,^$的意义就变成了匹配行的开始处和结束处

字符转义

如果你想查找元字符本身的话,比如你查找.,或者*,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\来取消这些字符的特殊意义。因此,你应该使用\.\*。当然,要查找\本身,你也得用\\.

例如:deerchao\.net匹配deerchao.netC:\\Windows匹配C:\Windows

重复

你已经看过了前面的*,+,{2},{5,12}这几个匹配重复的方式了。下面是正则表达式中所有的限定符(指定数量的代码,例如*,{5,12}等):

表2.常用的限定符
代码/语法 说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

下面是一些使用重复的例子:

Windows\d+匹配Windows后面跟1个或更多数字

^\w+匹配一行的第一个单词(或整个字符串的第一个单词,具体匹配哪个意思得看选项设置)

字符类

要想查找数字,字母或数字,空白是很简单的,因为已经有了对应这些字符集合的元字符,但是如果你想匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u),应该怎么办?

很简单,你只需要在方括号里列出它们就行了,像[aeiou]就匹配任何一个英文元音字母[.?!]匹配标点符号(.或?或!)

我们也可以轻松地指定一个字符范围,像[0-9]代表的含意与\d就是完全一致的:一位数字;同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)。

下面是一个更复杂的表达式:\(?0\d{2}[) -]?\d{8}

“(”和“)”也是元字符,后面的分组节里会提到,所以在这里需要使用转义

这个表达式可以匹配几种格式的电话号码,像(010)88886666,或022-22334455,或02912345678等。我们对它进行一些分析吧:首先是一个转义字符\(,它能出现0次或1次(?),然后是一个0,后面跟着2个数字(\d{2}),然后是)-空格中的一个,它出现1次或不出现(?),最后是8个数字(\d{8})。

分枝条件

不幸的是,刚才那个表达式也能匹配010)12345678(022-87654321这样的“不正确”的格式。要解决这个问题,我们需要用到分枝条件。正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开。听不明白?没关系,看例子:

0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)

\(?0\d{2}\)?[- ]?\d{8}|0\d{2}[- ]?\d{8}这个表达式匹配3位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间隔,也可以没有间隔。你可以试试用分枝条件把这个表达式扩展成也支持4位区号的。

\d{5}-\d{4}|\d{5}这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:使用分枝条件时,要注意各个条件的顺序。如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。

分组

我们已经提到了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作(后面会有介绍)。

(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})。

IP地址中每个数字都不能大于255. 经常有人问我, 01.02.03.04 这样前面带有0的数字, 是不是正确的IP地址呢? 答案是: 是的, IP 地址里的数字可以包含有前导 0 (leading zeroes).

不幸的是,它也将匹配256.300.888.999这种不可能存在的IP地址。如果能使用算术比较的话,或许能简单地解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的IP地址:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)

理解这个表达式的关键是理解2[0-4]\d|25[0-5]|[01]?\d\d?,这里我就不细说了,你自己应该能分析得出来它的意义。

反义

有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义

表3.常用的反义代码
代码/语法 说明
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

例子:\S+匹配不包含空白符的字符串

<a[^>]+>匹配用尖括号括起来的以a开头的字符串

后向引用

使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

呃……其实,组号分配还不像我刚说得那么简单:

  • 分组0对应整个正则表达式
  • 实际上组号分配过程是要从左向右扫描两遍的:第一遍只给未命名组分配,第二遍只给命名组分配--因此所有命名组的组号都大于未命名的组号
  • 你可以使用(?:exp)这样的语法来剥夺一个分组对组号分配的参与权.

后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本。难以理解?请看示例:

\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 或者kitty kitty。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。

你也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)(或者把尖括号换成'也行:(?'Word'\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b

使用小括号的时候,还有很多特定用途的语法。下面列出了最常用的一些:

表4.常用分组语法
分类 代码/语法 说明
捕获 (exp) 匹配exp,并捕获文本到自动命名的组里
(?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp)
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
零宽断言 (?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读

我们已经讨论了前两种语法。第三个(?:exp)不会改变正则表达式的处理方式,只是这样的组匹配的内容不会像前两种那样被捕获到某个组里面,也不会拥有组号。“我为什么会想要这样做?”——好问题,你觉得为什么呢?

零宽断言

地球人,是不是觉得这些术语名称太复杂,太难记了?我也有同感。知道有这么一种东西就行了,它叫什么,随它去吧!人若无名,便可专心练剑;物若无名,便可随意取舍……

接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。最好还是拿例子来说明吧:

断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。

(?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配singdanc

(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading

假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了),你可以这样查找需要在前面和里面添加逗号的部分:((?<=\d)\d{3})+\b,用它对1234567890进行查找时结果是234567890

下面这个例子同时使用了这两种断言:(?<=\s)\d+(?=\s)匹配以空白符间隔的数字(再次强调,不包括这些空白符)

负向零宽断言

前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样:

\b\w*q[^u]\w*\b匹配包含后面不是字母u的字母q的单词。但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的\w*\b将会匹配下一个单词,于是\b\w*q[^u]\w*\b就能匹配整个Iraq fighting负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:\b\w*q(?!u)\w*\b

零宽度负预测先行断言(?!exp)断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词

同理,我们可以用(?<!exp),零宽度负回顾后发断言断言此位置的前面不能匹配表达式exp(?<![a-z])\d{7}匹配前面不是小写字母的七位数字

请详细分析表达式(?<=<(\w+)>).*(?=<\/\1>),这个表达式最能表现零宽断言的真正用途。

一个更复杂的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容(?<=<(\w+)>)指定了这样的前缀被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最后是一个后缀(?=<\/\1>)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的是<b>和</b>之间的内容(再次提醒,不包括前缀和后缀本身)。

注释

小括号的另一种用途是通过语法(?#comment)来包含注释。例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)

要包含注释的话,最好是启用“忽略模式里的空白符”选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。例如,我们可以前面的一个表达式写成这样:

      (?<=    # 断言要匹配的文本的前缀
  <(\w+)> # 查找尖括号括起来的字母或数字(即HTML/XML标签)
  )       # 前缀结束
  .*      # 匹配任意文本
  (?=     # 断言要匹配的文本的后缀
  <\/\1>  # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签
  )       # 后缀结束

贪婪与懒惰

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。

有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。现在看看懒惰版的例子吧:

a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)ab(第四到第五个字符)

为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权——The match that begins earliest wins。

表5.懒惰限定符
代码/语法 说明
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

处理选项

在C#中,你可以使用Regex(String, RegexOptions)构造函数来设置正则表达式的处理选项。如:Regex regex = new Regex(@"\ba\w{6}\b", RegexOptions.IgnoreCase);

上面介绍了几个选项如忽略大小写,处理多行等,这些选项能用来改变处理正则表达式的方式。下面是.Net中常用的正则表达式选项:

表6.常用的处理选项
名称 说明
IgnoreCase(忽略大小写) 匹配时不区分大小写。
Multiline(多行模式) 更改^$的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,$的精确含意是:匹配\n之前的位置以及字符串结束前的位置.)
Singleline(单行模式) 更改.的含义,使它与每一个字符匹配(包括换行符\n)。
IgnorePatternWhitespace(忽略空白) 忽略表达式中的非转义空白并启用由#标记的注释。
ExplicitCapture(显式捕获) 仅捕获已被显式命名的组。

一个经常被问到的问题是:是不是只能同时使用多行模式和单行模式中的一种?答案是:不是。这两个选项之间没有任何关系,除了它们的名字比较相似(以至于让人感到疑惑)以外。

平衡组/递归匹配

这里介绍的平衡组语法是由.Net Framework支持的;其它语言/库不一定支持这种功能,或者支持此功能但需要使用不同的语法。

有时我们需要匹配像( 100 * ( 50 + 15 ) )这样的可嵌套的层次性结构,这时简单地使用\(.+\)则只会匹配到最左边的左括号和最右边的右括号之间的内容(这里我们讨论的是贪婪模式,懒惰模式也有下面的问题)。假如原来的字符串里的左括号和右括号出现的次数不相等,比如( 5 / ( 3 + 2 ) ) ),那我们的匹配结果里两者的个数也不会相等。有没有办法在这样的字符串里匹配到最长的,配对的括号之间的内容呢?

为了避免(\(把你的大脑彻底搞糊涂,我们还是用尖括号代替圆括号吧。现在我们的问题变成了如何把xx <aa <bbb> <bbb> aa> yy这样的字符串里,最长的配对的尖括号内的内容捕获出来?

这里需要用到以下的语法构造:

  • (?'group') 把捕获的内容命名为group,并压入堆栈(Stack)
  • (?'-group') 从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败
  • (?(group)yes|no) 如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分
  • (?!) 零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败

如果你不是一个程序员(或者你自称程序员但是不知道堆栈是什么东西),你就这样理解上面的三种语法吧:第一个就是在黑板上写一个"group",第二个就是从黑板上擦掉一个"group",第三个就是看黑板上写的还有没有"group",如果有就继续匹配yes部分,否则就匹配no部分。

我们需要做的是每碰到了左括号,就在压入一个"Open",每碰到一个右括号,就弹出一个,到了最后就看看堆栈是否为空--如果不为空那就证明左括号比右括号多,那匹配就应该失败。正则表达式引擎会进行回溯(放弃最前面或最后面的一些字符),尽量使整个表达式得到匹配。

<                         #最外层的左括号
[^<>]*                #最外层的左括号后面的不是括号的内容
(
    (
        (?'Open'<)    #碰到了左括号,在黑板上写一个"Open"
        [^<>]*       #匹配左括号后面的不是括号的内容
    )+
    (
        (?'-Open'>)   #碰到了右括号,擦掉一个"Open"
        [^<>]*        #匹配右括号后面不是括号的内容
    )+
)*
(?(Open)(?!))         #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败

>                         #最外层的右括号

平衡组的一个最常见的应用就是匹配HTML,下面这个例子可以匹配嵌套的<div>标签<div[^>]*>[^<>]*(((?'Open'<div[^>]*>)[^<>]*)+((?'-Open'</div>)[^<>]*)+)*(?(Open)(?!))</div>.

还有些什么东西没提到

上边已经描述了构造正则表达式的大量元素,但是还有很多没有提到的东西。下面是一些未提到的元素的列表,包含语法和简单的说明。你可以在网上找到更详细的参考资料来学习它们--当你需要用到它们的时候。如果你安装了MSDN Library,你也可以在里面找到.net下正则表达式详细的文档。这里的介绍很简略,如果你需要更详细的信息,而又没有在电脑上安装MSDN Library,可以查看关于正则表达式语言元素的MSDN在线文档

表7.尚未详细讨论的语法
代码/语法 说明
\a 报警字符(打印它的效果是电脑嘀一声)
\b 通常是单词分界位置,但如果在字符类里使用代表退格
\t 制表符,Tab
\r 回车
\v 竖向制表符
\f 换页符
\n 换行符
\e Escape
\0nn ASCII代码中八进制代码为nn的字符
\xnn ASCII代码中十六进制代码为nn的字符
\unnnn Unicode代码中十六进制代码为nnnn的字符
\cN ASCII控制字符。比如\cC代表Ctrl+C
\A 字符串开头(类似^,但不受处理多行选项的影响)
\Z 字符串结尾或行尾(不受处理多行选项的影响)
\z 字符串结尾(类似$,但不受处理多行选项的影响)
\G 当前搜索的开头
\p{name} Unicode中命名为name的字符类,例如\p{IsGreek}
(?>exp) 贪婪子表达式
(?<x>-<y>exp) 平衡组
(?im-nsx:exp) 在子表达式exp中改变处理选项
(?im-nsx) 为表达式后面的部分改变处理选项
(?(exp)yes|no) 把exp当作零宽正向先行断言,如果在这个位置能匹配,使用yes作为此组的表达式;否则使用no
(?(exp)yes) 同上,只是使用空表达式作为no
(?(name)yes|no) 如果命名为name的组捕获到了内容,使用yes作为表达式;否则使用no
(?(name)yes) 同上,只是使用空表达式作为no

联系作者

好吧,我承认,我骗了你,读到这里你肯定花了不止30分钟.相信我,这是我的错,而不是因为你太笨.我之所以说"30分钟",是为了让你有信心,有耐心继续下去.既然你看到了这里,那证明我的阴谋成功了.被忽悠的感觉很爽吧?

要投诉我,或者觉得我其实可以忽悠得更高明,欢迎来我的微博让我知道. 如果你有关于正则表达式的问题, 可以到 stackoverflow 网站上提问, 记得要添加 regex 标签. 如果你更习惯于用中文交流, 可以到微博上用 #正则# 标签提出问题.

网上的资源及本文参考文献

更新纪录

  1. 2006-3-27 第一版
  2. 2006-10-12 第二版
    • 修正了几个细节上的错误和不准确的地方
    • 增加了对处理中文时的一些说明
    • 更改了几个术语的翻译(采用了MSDN的翻译方式)
    • 增加了平衡组的介绍
    • 放弃了对The Regulator的介绍,改用Regex Tester
  3. 2007-3-12 V2.1
    • 修正了几个小的错误
    • 增加了对处理选项(RegexOptions)的介绍
  4. 2007-5-28 V2.2
    • 重新组织了对零宽断言的介绍
    • 删除了几个不太合适的示例,添加了几个实用的示例
    • 其它一些微小的更改
  5. 2007-8-3 V2.21
    • 修改了几处文字错误
    • 修改/添加了对$,\b的精确说明
    • 承认了作者是个骗子
    • 给RegexTester添加了Singleline选项的相关功能
  6. 2008-4-13 v2.3
    • 调整了部分章节的次序
    • 修改了页面布局,删除了专门的参考节
    • 针对读者的反馈,调整了部分内容
  7. 2009-4-11 v2.31
    • 修改了几处文字错误
    • 添加了一些注释说明
    • 调整了一些措词
  8. 2011-8-17 v2.32
    • 更改了工具介绍,换用自行开发的正则表达式测试器
  9. 2013-1-10 v2.33
    • 说明包含前导0的IP地址是合法的

[GRUB4DOS] 未公开特性:扇区序列文件的长度指定,精确到字节

发表于

我觉得这是一个未公开的特性,因为我从未在其它地方见到过有关这一特性的描述。

在 grub 中,我们可以用 (hd0)12345+8 或者 (hd0,0)2+20,33+5,87+300 之类的表达法来表示一个磁盘文件。这种表示法,就是扇区序列表示法。既然是扇区序列,那么这样的文件,就只能以扇区对齐(也即必须为 512 的整数倍),也就是说,不可能表示一个256 字节的文件,也不可能表示一个 513 字节的文件。

对于内存文件来讲,也是如此,(md)xxxxx+yyyyy(rd)xxxxx+yyyyy 这类表达法都是表示扇区的整数倍,这样大小的文件。

然而有时候,我们确实需要精确到字节的扇区序列文件。比如在硬盘上(或内存中)有一个 image.gz 文件,如果你不指定这个文件的精确大小,那么grub 就不能正常解压这个文件,这是因为解压程序依赖于这个 gz 的精确长度,你多一个字节或少一个字节,都可能会失败的。

怎样指定扇区序列的精确长度呢?这可能是 GNU GRUB 早期的开发者早就开发的功能了,只是没有公开,也许是因为开发者觉得这个功能的实现方法以后说不定会改变,就不适合公开了。扇区序列的精确长度(以字节计),是直接加在扇区序列表达法之后的,用逗号与扇区序列隔开。例如,你想打印出 MBR 中开头的 466 个字节,就可以这样:

cat --hex (hd0)+1,466

其中 (hd0)+1 是扇区序列,466 表示只从扇区序列中取出 466 字节作为文件的长度。

再举一例:

cat --hex (hd0)+63,800+63,64400

如果没有结尾的“,64400”,那么,“(hd0)+63,800+63”就表示不连续的两个扇区序列所组成的文件,每个连续的序列都有 63 个扇区,所以文件总共有 126 个扇区。文件的长度就是 126x512=64512 字节。加上了结尾的“,64400”之后,文件变小了,它表示的文件长度为 64400。当然你不应该指定一个长度,使得它比扇区序列的总长度还要大。

但是,如果你想只访问 MBR 中的分区表,那是不行的,这种表达法不支持从扇区序列的中间截取文件,只支持从扇区序列的最开头截取一定长度的文件。

由于这种表达法也是有缺点的,因此我们也仍然不公开这一特性。今后说不定会出现一种更合理的表达方式。

GRUB4DOS一个比较变态的用法(利用GRUB4DOS作为文件中转站)

发表于

利用GRUB4DOS的map功能来中转文件.使得DOS下可以访问
例子:

map --mem /minipe/system.wim (hd1)
map --hook

说明: 把/MINIPE.SYSTEM.WIM文件映射为(hd1)硬盘.GRUB4DOS会把这个文件的内容作为一个磁盘分区(hd1,0).

也就是把一个文件虚拟成一个分区.

然后进到入DOS后,利用一个磁盘工具把上面的(hd1,0)分区保存为一个文件.
例子:用todisk

todisk 2:1=q to (c:\system.wim)

把第二磁盘的第一分区保存为system.wim(即还原过程).

这个方法在某些情况下很有用处.由于1个磁盘扇区是512字节,所以最后得到的文件会是512字节的倍数(不足补00),所以只适用于对文件内容长度要求不是很严格的地方.

解决电脑远程登陆出现 “远程计算机已结束连接”

发表于

此贴转自时空论坛 原贴: http://bbs.znpc.net/viewthread.php?tid=3304

转到这里留个备份,以后再碰到这个问题比较好找.^_^

解决电脑远程登陆出现 远程计算机已结束连接

此问题在远程系统是GHOST版的windowsxp时出现的比较普遍。

现象描述:

用windowsxp自带的远程桌面功能连接到另外一台windowsxp电脑时,在连接的瞬间便
弹出远程计算机已结束连接的出错窗口。

解决方法:

打开注册表
找到[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\Root\RDPDR\
在左侧的 RDPDR 上右键-权限,选上完全控制,把以下注册表内容.复制到记事本保存为reg文件.
再导入注册表:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\Root\RDPDR\0000]
"ClassGUID"="{4D36E97D-E325-11CE-BFC1-08002BE10318}"
"Class"="System"
"HardwareID"=hex(7):52,00,4f,00,4f,00,54,00,5c,00,52,00,44,00,50,00,44,00,52,00,00,00,00,00
"Driver"="{4D36E97D-E325-11CE-BFC1-08002BE10318}\0030"
"Mfg"="(标准系统设备)"
"Service"="rdpdr"
"DeviceDesc"="终端服务器设备重定向器"
"ConfigFlags"=dword:00000000
"Capabilities"=dword:00000000

最后,把控制面板-管理工具-服务中的 Remote Desktop Help Session ManagerTelnet 服务开启,
将电脑重启,远程桌面管理就可以恢复正常了。

注:可能是因为做GHOST系统时,为了省事在删除硬件时直接使用了devcon remove *,所以才会出现这个问题.