顯示包含「電腦」標籤的文章。顯示所有文章
顯示包含「電腦」標籤的文章。顯示所有文章

2009年3月5日

PHP抓網頁內容

此摘要無法顯示。請 按一下這裡以查看文章。

2009年3月2日

如何对付“无线蹭网”?

小村
image
image
image
image
image
image 带大功率天线的蹭网设备

■网乐 文/小村

最近,“无线蹭网”成了全国各地媒体声讨的对象。就像有网络就有黑客一样,自从有无线网络以来,“无线蹭网”就像个寄生虫一样,始终形影不离。家里安装无线网络的用户越来越多,蹭网的人也越来越多。

搜索引擎上可以搜索到一大堆“教你如何蹭网”的简易手册,淘宝上也能搜索到一大堆卖“蹭网设备”的网店。    实际上,并不是每个蹭网的人都是黑客高手,只要给你家里的无线网络设置一定的安全措施,被人蹭网的概率就会大大降低。当然,你家门上都不安锁,自然就会有人顺手牵羊。

A 不让小偷盯上你

安全策略:隐藏你的无线网络ID

安全指数:★★【【【

当你买了无线路由器在家布置了无线网络后,你家里就有了一个Wi-Fi无线网络环境了。打开你的笔记本或其他移动设备,寻找无线网络时,就可以看到有很多网络名字,这些名字就是服务设定标识(SSID)。

当你购买一个无线路由器后,默认的SSID一般都和该路由器的品牌相关联。比如你买的是TP-Link,你的SSID号开始肯定以TP-Link开头。一个黑客可以轻松通过你的SSID知道你的路由器品牌。你可以在无线路由的管理界面上,修改这个SSID,改成你喜欢的名字,这样起码可以在一定程度上隐蔽你的无线路由。

修改SSID只是最简单的方式,我们还可以通过关闭SSID广播来起到更好的效果。以Linksys管理界面为例,SETUP选项中,SSID Broadcast就可以选择Disable,这样就关闭了SSID。这样你的无线网络,对于一般人来说,就是隐蔽了。

这时,在你自己的笔记本上,点击“查看无线网络”按钮。以Windows XP为例,在修改高级设置链接中,然后点击无线网络配置标签。在首选网络部分点击增加按钮,然后输入你修改后的SSID,点击确认,你就可以连接到你的无线网络中了。一般人不知道你的无线网络SSID,所以安全性得到了一定提高。

B 门前上个锁

安全策略:加密你的无线网络

安全指数:★★★【【

时下,一般无线路由都提供两种加密标准:无线对等协议(WEP)和Wi-Fi保护接入(WPA)。WEP要比WPA老,但是不如WPA安全。目前网上流行的,“10分钟可破解无线路由器密码”,指的就是破解WEP密码。所以,采用WPA会更安全些,起码给黑客制造更多的麻烦。

设置加密后,需要无线上网的电脑上查看无线网络属性,在网络密钥对话框中输入密码,你的PC就可以连接到你的使用WPA加密的无线网络了。

C 筛选你的访客

安全策略:使用MAC地址过滤

安全指数:★★★★【

每一个网络设备都有唯一的被称作MAC地址的ID,一般是这种格式:00-D8-A1-40-9F-62。你可以利用他来据入侵者于门外。许多路由器允许你设定一个范围的MAC地址可以接入到互联网。这样你可以告诉无线路由器哪些是你自己的PC的MAC地址,不属于这个范围的一律拒之门外。

如何查看自己电脑网卡的MAC地址的ID呢?在Windows系统中点选“开始菜单”,然后选“运行”,弹出的对话框中输入“cmd ”,回车后会出现命令行窗口。在命令行窗口中输入 ipconfig /all。寻找名为“Physical Address”的这一行,其后所显示的地址即为该设备的 MAC地址。

D 雇多个保安

安全策略:限定IP地址

安全指数:★★★★【

当你的计算机连接到你的网络中的时候,你的无线路由器通常会分给他一个IP地址,用他来浏览网页或连接外部互联网。通常情况下,无线路由器会给每一个连接到无线网络中来的每一台机器分配一个IP。

但是你可以告诉你的无线路由器只分配一定范围的IP地址,假如你的网络中的计算机使用了所有的IP地址的话,你的无线路由器就不会为入侵者再分配IP地址。

比如你家有两台无线上网电脑,你指定你的无线路由,只分配192.168.1.1至192.168.1.2,这样当你的两台电脑都上网时,别人就无法再分配IP了,而如果你哪天发现自己的电脑分配不到IP,就知道你楼下的保安给小偷干掉了。

■链接———

香港WiFi近五成可破解

据报道,在香港地区超过三万个WiFi无线网络热点中,有近五成可以在十分钟内破解。

据悉,香港无线科技商会和专业信息保安协会携手进行侦测WiFi网络,采集样本超三万个。侦测结果表明,约两成完全无加密,有47%采用不安全的WEP 加密方式,可于十分钟内被黑客破解,只有约31%采用较安全WPA制式。上述机构呼吁,市民应该在计算机自行设定较安全的加密方式。

2008年8月31日

正则表达式的五个成功习惯

正则表达式难于书写、难于阅读、难于维护,经常错误匹配意料不到的文本或者错过了有效的文本,这些问题都是由正则表达式的表现和能力引起的。每个元字符(metacharacter)的能力和细微差别组合在一起,使得代码不借助于智力技巧就无法解释。
     许多包含一定特性的工具使阅读和编写正则表达式变得容易了,但是它们又很不符合习惯。对于很多程序员来说,书写正则表达式就是一种魔法艺术。他们坚持自己所知道的特征并持有绝对乐观的态度。如果你愿意采用本文所探讨的五个习惯,你将可以让你设计的正则表达式经受的住反复试验。
    本文将使用Perl、PHP和Python语言作为代码示例,但是本文的建议几乎适用于任何替换表达式(regex)的执行。

    一、使用空格和注释
    对于大部分程序员来说,在一个正则表达式环境里使用空格和缩进排列都不成问题,如果他们没有这么做一定会被同行甚至外行人士看笑话。几乎每个人都知道把代码挤在一行会难于阅读、书写和维护。对于正则表达式又有什么不同呢?
    大部分替换表达式工具都具有扩展的空格特性,这允许程序员把他们的正则表达式扩展为多行,并在每一行结尾加上注释。为什么只有少部分程序员利用这个特性呢?Perl 6的正则表达式默认就是扩展空格的模式。不要再让语言替你默认扩展空格了,自己主动利用吧。
    记住扩展空格的窍门之一就是让正则表达式引擎忽略扩展空格。这样如果你需要匹配空格,你就不得不明确说明。
    在Perl语言里面,在正则表达式的结尾加上x,这样“m/foo|bar/”变为如下形式:
m/
  foo
  |
  bar
/x
    在PHP语言里面,在正则表达式的结尾加上x,这样“"/foo|bar/"”变为如下形式:
"/
  foo
  |
  bar
/x"
    在Python语言里面,传递模式修饰参数“re.VERBOSE”得到编译函数如下:
pattern = r'''
foo
|
bar
'''
regex = re.compile(pattern, re.VERBOSE)
    处理更加复杂的正则表达式时,空格和注释就更能体现出其重要性。假设下面的正则表达式用于匹配美国的电话号码:
\(?\d{3}\)? ?\d{3}[-.]\d{4}
     这个正则表达式匹配电话号码如“(314)555-4000”的形式,你认为这个正则表达式是否匹配“314-555-4000”或者“555- 4000”呢?答案是两种都不匹配。写上这么一行代码隐蔽了缺点和设计结果本身,电话区号是需要的,但是正则表达式在区号和前缀之间缺少一个分隔符号的说明。
    把这一行代码分成几行并加上注释将把缺点暴露无疑,修改起来显然更容易一些。
    在Perl语言里面应该是如下形式:
/  
    \(?     # 可选圆括号
      \d{3} # 必须的电话区号
    \)?     # 可选圆括号
    [-\s.]? # 分隔符号可以是破折号、空格或者句点
      \d{3} # 三位数前缀
    [-.]    # 另一个分隔符号
      \d{4} # 四位数电话号码
/x
    改写过的正则表达式现在在电话区号后有一个可选择的分隔符号,这样它应该是匹配“314-555-4000”的,然而电话区号还是必须的。另一个程序员如果需要把电话区号变为可选项则可以迅速看出它现在不是可选的,一个小小的改动就可以解决这个问题。

    二、书写测试
    一共有三个层次的测试,每一层为你的代码加上一层可靠性。首先,你需要认真想想你需要匹配什么代码以及你是否能够处理错误匹配。其次,你需要利用数据实例来测试正则表达式。最后,你需要正式通过一个测试小组的测试。
     决定匹配什么其实就是在匹配错误结果和错过正确结果之间寻求一个平衡点。如果你的正则表达式过于严格,它将会错过一些正确匹配;如果它过于宽松,它将会产生一个错误匹配。一旦某个正则表达式发放到实际代码当中,你可能不会两者都注意到。考虑一下上面电话号码的例子,它将会匹配“800-555-4000  = -5355”。错误的匹配其实很难发现,所以提前规划做好测试是很重要的。
    还是使用电话号码的例子,如果你在Web表单里面确认一个电话号码,你可能只要满足于任何格式的十位数字。但是,如果你想从大量文本里面分离电话号码,你可能需要很认证的排除不符合要求的错误匹配。
    在考虑你想匹配的数据的时候,写下一些案例情况。针对案例情况写下一些代码来测试你的正则表达式。任何复杂的正则表达式都最好写个小程序测试一下,可以采用下面的具体形式。
    在Perl语言里面:
#!/usr/bin/perl

my @tests = ( "314-555-4000",
              "800-555-4400",
       "(314)555-4000",
              "314.555.4000",
              "555-4000",
              "aasdklfjklas",
              "1234-123-12345"          
            );

foreach my $test (@tests) {
    if ( $test =~ m/
                   \(?     # 可选圆括号
                     \d{3} # 必须的电话区号
                   \)?     # 可选圆括号
                   [-\s.]? # 分隔符号可以是破折号、空格或者句点
                     \d{3} # 三位数前缀
                   [-\s.]  # 另一个分隔符号
                     \d{4} # 四位数电话号码
                   /x ) {
        print "Matched on $test\n";
     }
     else {
        print "Failed match on $test\n";
     }
}

    在PHP语言里面:
<?php
$tests = array( "314-555-4000",
           "800-555-4400",
           "(314)555-4000",
           "314.555.4000",
           "555-4000",
           "aasdklfjklas",
           "1234-123-12345"
          );

$regex = "/
            \(?     # 可选圆括号
              \d{3} # 必须的电话区号
            \)?     # 可选圆括号
            [-\s.]? # 分隔符号可以是破折号、空格或者句点
              \d{3} # 三位数前缀
            [-\s.]  # 另一个分隔符号
              \d{4} # 四位数电话号码
           /x";

foreach ($tests as $test) {
    if (preg_match($regex, $test)) { 
        echo "Matched on $test<br />;";
    }
    else {
        echo "Failed match on $test<br />;";
     }
}
?>;

        在Python语言里面:
import re

tests = ["314-555-4000",
         "800-555-4400",
         "(314)555-4000",
         "314.555.4000",
         "555-4000",
         "aasdklfjklas",
         "1234-123-12345"        
        ]

pattern = r'''
\(?                 # 可选圆括号
              \d{3} # 必须的电话区号
            \)?     # 可选圆括号
            [-\s.]? # 分隔符号可以是破折号、空格或者句点
              \d{3} # 三位数前缀
            [-\s.]  # 另一个分隔符号
              \d{4} # 四位数电话号码
           '''

regex = re.compile( pattern, re.VERBOSE )

for test in tests:
    if regex.match(test):
        print "Matched on", test, "\n"
    else:
        print "Failed match on", test, "\n"

    运行测试代码将会发现另一个问题:它匹配“1234-123-12345”。
     理论上,你需要整合整个程序所有的测试到一个测试小组里面。即使你现在还没有测试小组,你的正则表达式测试也会是一个小组的良好基础,现在正是开始创建的好机会。即使现在还不是创建的合适时间,你也应该在每次修改以后运行测试一下正则表达式。这里花费一小段时间将会减少你很多麻烦事。

    三、为交替操作分组
    交替操作符号(|)的优先级很低,这意味着它经常交替超过程序员所设计的那样。比如,从文本里面抽取Email地址的正则表达式可能如下:
^CC:|To:(.*)
    上面的尝试是不正确的,但是这个bug往往不被注意。上面代码的意图是找到“CC:”或者“To:”开始的文本,然后在这一行的后面部分提取Email地址。
     不幸的是,如果某一行中间出现“To:”,那么这个正则表达式将捕获不到任何以“CC:”开始的一行,而是抽取几个随机的文本。坦白的说,正则表达式匹配 “CC:”开始的一行,但是什么都捕获不到;或者匹配任何包含“To:”的一行,但是把这行的剩余文本都捕获了。通常情况下,这个正则表达式会捕获大量 Email地址,所有没有人会注意这个bug。
    如果要符合实际意图,那么你应该加入括号说明清楚,正则表达式如下:
(^CC:)|(To:(.*))
    如果真正意图是捕获以“CC:”或者“To:”开始的文本行的剩余部分,那么正确的正则表达式如下:
^(CC:|To:)(.*)
    这是一个普遍的不完全匹配的bug,如果你养成为交替操作分组的习惯,你就会避免这个错误。

    四、使用宽松数量词
    很多程序员避免使用宽松数量词比如“*?”、“+?”和“??”,即使它们会使这个表达式易于书写和理解。
     宽松数量词可以尽可能少的匹配文本,这样有助于完全匹配的成功。如果你写了“foo(.*?)bar”,那么数量词将在第一次遇到“bar”时就停止匹配,而不是在最后一次。如果你希望从“foo###bar+++bar”中捕获“###”,这一点就很重要。一个严格数量词将捕获“###bar++ +”。
    假设你要从HTML文件里面捕获所有电话号码,你可能会使用我们上文讨论过的电话号码正则表达式的例子。但是,如果你知道所有电话号码都在一个表格的第一列里面,你可以使用宽松数量词写出更简单的正则表达式:
<tr>;<td>;(.+?)<td>;
    很多刚起步的程序员不使用宽松数量词来否定特定种类。他们能写出下面的代码:
<tr>;<td>;([^>;]+)</td>;
    这种情况下它可以正常运行,但是如果你想捕获的文本包含有你分隔的公共字符(这种情况下比如</td>;),这将会带来很大麻烦。如果你使用了宽松数量词,你只要花上很少的时间组装字符种类就能产生新的正则表达式。
    在你知道你要捕获文本的环境结构时,宽松数量词是具有很大价值的。

    五、利用可用分界符
    Perl 和PHP语言常常使用左斜线(/)来标志一个正则表达式的开头和结尾,Python语言使用一组引号来标志开头和结尾。如果在Perl和PHP中坚持使用左斜线,你将要避免表达式中的任何斜线;如果在Python中使用引号,你将要避免使用反斜线(\)。选择不同的分界符或引号可以允许你避免一半的正则表达式。这将使得表达式易于阅读,减少由于忘记避免符号而潜在的bug。
    Perl和PHP语言允许使用任何非数字和空格字符作为分界符。如果你切换到一个新的分界符,在匹配URL或HTML标志(如“http://”或“<br/>;”)时,你就可以避免漏掉左斜线了。
    例如,“/http:\/\/(\S)*/”可以写为“#http://(\S)*#”。
    通用分界符是“#”、“!”和“|”。如果你要使用方括号、尖括号或者花括号,只要保持前后配对出现就可以了。下面就是一些通用分界符的示例:
#…# !…! {…} s|…|…| (Perl only) s[…][…] (Perl only) s<…>;/…/ (Perl only) 
     在Python中,正则表达式首先会被当作一个字符串。如果你使用引号作为分界符,你将漏掉所有反斜线。但是你可以使用“r''”字符串避免这个问题。如果针对“re.VERBOSE”选项使用三个连续单引号,它将允许你包含换行。例如 regex = "(\\w+)(\\d+)"可以写出下面的形式:
regex = r'''
           (\w+)
           (\d+)
         '''

    小结:本文的建议主要着眼于正则表达式的可读性,在开发中养成这些习惯,你将会更加清晰的考虑设计和表达式的结构,这将有助于减少bug和代码的维护,如果你自己就是这个代码的维护者你将倍感轻松。

http://www.phpv.net/html/1506.html

半小时精通正则表达式!

想必很多人都对正则表达式都头疼.今天,我以我的认识,加上网上一些文章,希望用常人都可以理解的表达方式.来和大家分享学习经验.

  开篇,还是得说说 ^  和  $  他们是分别用来匹配字符串的开始和结束,以下分别举例说明

"^The": 开头一定要有"The"字符串;
"of despair$":  结尾一定要有"of despair" 的字符串;

那么,
"^abc$": 就是要求以abc开头和以abc结尾的字符串,实际上是只有abc匹配
"notice": 匹配包含notice的字符串

你可以看见如果你没有用我们提到的两个字符(最后一个例子),就是说 模式(正则表达式) 可以出现在被检验字符串的任何地方,你没有把他锁定到两边
接着,说说 '*', '+',和 '?',
他们用来表示一个字符可以出现的次数或者顺序. 他们分别表示:
"zero or more"相当于{0,},
"one or more"相当于{1,}, 
"zero or one."相当于{0,1},  这里是一些例子:

"ab*":  和ab{0,}同义,匹配以a开头,后面可以接0个或者N个b组成的字符串("a", "ab", "abbb", 等);
"ab+": 和ab{1,}同义,同上条一样,但最少要有一个b存在 ("ab", "abbb", 等.);
"ab?":和ab{0,1}同义,可以没有或者只有一个b;
"a?b+$": 匹配以一个或者0个a再加上一个以上的b结尾的字符串.

要点, '*', '+',和 '?'只管它前面那个字符.

你也可以在大括号里面限制字符出现的个数,比如

"ab{2}": 要求a后面一定要跟两个b(一个也不能少)("abb");
"ab{2,}": 要求a后面一定要有两个或者两个以上b(如"abb", "abbbb", 等.);
"ab{3,5}": 要求a后面可以有2-5个b("abbb", "abbbb", or "abbbbb").

现在我们把一定几个字符放到小括号里,比如:
"a(bc)*": 匹配 a 后面跟0个或者一个"bc";
"a(bc){1,5}": 一个到5个 "bc."

还有一个字符 '│', 相当于OR 操作:

"hi│hello": 匹配含有"hi" 或者 "hello" 的 字符串;
"(b│cd)ef": 匹配含有 "bef" 或者 "cdef"的字符串;
"(a│b)*c": 匹配含有这样多个(包括0个)a或b,后面跟一个c
的字符串;

一个点('.')可以代表所有的单一字符,不包括"\n"

如果,要匹配包括"\n"在内的所有单个字符,怎么办?

对了,用'[\n.]'这种模式.

"a.[0-9]": 一个a加一个字符再加一个0到9的数字
"^.{3}$": 三个任意字符结尾 .

中括号括住的内容只匹配一个单一的字符

"[ab]": 匹配单个的 a 或者 b ( 和 "a│b" 一样);
"[a-d]": 匹配'a' 到'd'的单个字符 (和"a│b│c│d" 还有 "[abcd]"效果一样); 一般我们都用[a-zA-Z]来指定字符为一个大小写英文
"^[a-zA-Z]": 匹配以大小写字母开头的字符串
"[0-9]%": 匹配含有 形如 x% 的字符串
",[a-zA-Z0-9]$": 匹配以逗号再加一个数字或字母结尾的字符串

你也可以把你不想要得字符列在中括号里,你只需要在总括号里面使用'^' 作为开头 "%[^a-zA-Z]%" 匹配含有两个百分号里面有一个非字母的字符串.
要点:^用在中括号开头的时候,就表示排除括号里的字符

为了PHP能够解释,你必须在这些字符面前后加'',并且将一些字符转义.

不要忘记在中括号里面的字符是这条规路的例外―在中括号里面, 所有的特殊字符,包括(''), 都将失去他们的特殊性质 "[*\+?{}.]"匹配含有这些字符的字符串.

还有,正如regx的手册告诉我们: "如果列表里含有 ']', 最好把它作为列表里的第一个字符(可能跟在'^'后面). 如果含有'-', 最好把它放在最前面或者最后面, or 或者一个范围的第二个结束点[a-d-0-9]中间的‘-’将有效.

看了上面的例子,你对{n,m}应该理解了吧.要注意的是,n和m都不能为负整数,而且n总是小于m. 这样,才能 最少匹配n次且最多匹配m次. 如"p{1,5}"将匹配 "pvpppppp"中的前五个p

下面说说以\开头的

\b 书上说他是用来匹配一个单词边界,就是...比如've\b',可以匹配love里的ve而不匹配very里有ve

\B 正好和上面的\b相反.例子我就不举了

.....突然想起来....可以到http://www.phpv.net/article.php/251 看看其它用\ 开头的语法

好,我们来做个应用:

如何构建一个模式来匹配 货币数量 的输入

构建一个匹配模式去检查输入的信息是否为一个表示money的数字。我们认为一个表示money的数量有四种方式: "10000.00" 和 "10,000.00",或者没有小数部分, "10000" and "10,000". 现在让我们开始构建这个匹配模式:

^[1-9][0-9]*$

这是所变量必须以非0的数字开头.但这也意味着 单一的 "0" 也不能通过测试. 以下是解决的方法:

^(0│[1-9][0-9]*)$

"只有0和不以0开头的数字与之匹配",我们也可以允许一个负号在数字之前:

^(0│-?[1-9][0-9]*)$

这就是: "0 或者 一个以0开头 且可能 有一个负号在前面的数字." 好了,现在让我们别那么严谨,允许以0开头.现在让我们放弃 负号 , 因为我们在表示钱币的时候并不需要用到. 我们现在指定 模式 用来匹配小数部分:

^[0-9]+(\.[0-9]+)?$

这暗示匹配的字符串必须最少以一个阿拉伯数字开头. 但是注意,在上面模式中 "10." 是不匹配的, 只有 "10" 和 "10.2" 才可以. (你知道为什么吗)

^[0-9]+(\.[0-9]{2})?$

我们上面指定小数点后面必须有两位小数.如果你认为这样太苛刻,你可以改成:

^[0-9]+(\.[0-9]{1,2})?$

这将允许小数点后面有一到两个字符. 现在我们加上用来增加可读性的逗号(每隔三位), 我们可以这样表示:

^[0-9]{1,3}(,[0-9]{3})*(\.[0-9]{1,2})?$

不要忘记 '+' 可以被 '*' 替代 如果你想允许空白字符串被输入话 (为什么?). 也不要忘记反斜杆 ’\’ 在php字符串中可能会出现错误 (很普遍的错误).

现在,我们已经可以确认字符串了, 我们现在把所有逗号都去掉 str_replace(",", "", $money) 然后在把类型看成 double然后我们就可以通过他做数学计算了.

再来一个:

构造检查email的正则表达式

在一个完整的email地址中有三个部分: 
1. 用户名 (在 '@' 左边的一切),
2.'@',
3. 服务器名(就是剩下那部分).
用户名可以含有大小写字母阿拉伯数字,句号 ('.'), 减号('-'), and 下划线 ('_'). 服务器名字也是符合这个规则,当然下划线除外.

现在, 用户名的开始和结束都不能是句点. 服务器也是这样. 还有你不能有两个连续的句点他们之间至少存在一个字符,好现在我们来看一下怎么为用户名写一个匹配模式:

^[_a-zA-Z0-9-]+$

现在还不能允许句号的存在. 我们把它加上:

^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*$

上面的意思就是说: "以至少一个规范字符(除了.)开头,后面跟着0个或者多个以点开始的字符串."

简单化一点, 我们可以用 eregi()取代 ereg().eregi()对大小写不敏感, 我们就不需要指定两个范围 "a-z" 和 "A-Z"

http://www.phpv.net/html/1415.html

Javascript经典正则表达式

三道测试题:
1, var str=“ abbbbacc”;
var rs=str.replace(“a”,”0”);   
(A)0bbbbacc (B)0bbbb0cc
2,var str=“ abbbbacc”;
var rs=str.replace(“/a/”,”0”);   
(A)0bbbbacc (B)0bbbb0cc
3,var str=“ abbbbacc”;
var rs=str.replace(“/a/g”,”0”);   
(A)0bbbbacc (B)0bbbb0cc
附注:String对象的replace方法签名为:
replace(regx,str)
一,概述

1,正则表达式,可以说是任何一种编程语言都提供的机制,它主要是提供了对字符串的处理能力。
2,正则表达式在页面处理中的使用场景:
1)表单验证。验证某些域符合某种规则,例如邮件输入框必须输入的是邮件、联系电话输入框输入的必须是数字等等
2)处理DOM模型。例如通过表达式定位DOM中的一个对象或一系列对象,一个例子就是定位id属性中含有某个特殊字符的div对象。
3)纯编程逻辑。直接用于编程的逻辑之中。
3,说明:本部分所举的正则表达式的代码片断,都是经过测试的,但有一点需要注意,对于换行的字符串的定义,我们在表述时使用的是类似如下的形式:
var str=“It’s is
a  beautiful city”;
这种形式直接写在JS代码中是错误的,那如何获取具有换行的字符串呢?简单的办法:在textarea中输入文本并换行,然后将该值赋给JS变量即可。例如:
var str=document.forms[0].mytextarea.value;         

二,语法与使用

1,定义正则表达式

1)定义正则表达式有两种形式,一种是普通方式,一种是构造函数方式。
2)普通方式:var reg=/表达式/附加参数
表达式:一个字符串,代表了某种规则,其中可以使用某些特殊字符,来代表特殊的规则,后面会详细说明。
附加参数:用来扩展表达式的含义,目前主要有三个参数:
g:代表可以进行全局匹配。
i:代表不区分大小写匹配。
m:代表可以进行多行匹配。
上面三个参数,可以任意组合,代表复合含义,当然也可以不加参数。
例子:
var reg=/a*b/;
var reg=/abc+f/g;
3)构造函数方式:var reg=new RegExp(“表达式”,”附加参数”);
其中“表达式”与“附加参数”的含义与上面那种定义方式中的含义相同。
例子:
var reg=new RegExp(“a*b”);
var reg=new RegExp(“abc+f”,”g”);
4)普通方式与构造函数方式的区别
普通方式中的表达式必须是一个常量字符串,而构造函数中的表达式可以是常量字符串,也可以是一个js变量,例如根据用户的输入来作为表达式参数等等:
var reg=new RegExp(document.forms[0].exprfiled.value,”g”);

2,表达式模式

1)表达式模式,是指表达式的表达方式与样式, 即 var reg=/表达式/附加参数 中的“表达式”怎样去描述?
2)从规范上讲,表达式模式分为简单模式和复合模式。
3)简单模式:是指通过普通字符的组合来表达的模式,例如
var reg=/abc0d/;
可见简单模式只能表示具体的匹配。
4)复合模式:是指含有通配符来表达的模式,例如:
var reg=/a+b?\w/;
其中的+、?和\w都属于通配符,代表着特殊的含义。因此复合模式可以表达更为抽象化的逻辑。
下面我们着重说一下复合模式中各个通配符的含义及其使用。
5)复合模式中特殊字符的讲解:

1>\:在许多编程语言里面被用作转义符,一般来说
\符号后面如果跟的是普通字符c,那么\c就代表特殊的含义,例如n本来代表字符n,但\n就代表换行。
\符号后面如果跟的是特殊字符c,那么\c就代表普通字符c,例如\一般用作转义符,但\\则调表普通字符\。
Javascript的正则表达式中\的用法与上面相同,只是不同的编程语言,特殊字符表可能不太一样罢了。

2>^:匹配输入字符串的起始端,如果是多行匹配,即表达式的附加参数中含有m,则也在一个换行符后匹配。
例子:/^B/匹配 “Bab Bc ”中的第一个B
例子2:/^B/gm匹配
          “Badd B
          cdaf
          B dsfB”
          中的第一行第一个B,第三行中的第一个B
3>$:匹配输入字符创的尾端,如果是多行匹配,即表达式的附加参数中含有m,则也在一个换行符前匹配。
与^的用法相反。
例子:/t$/匹配“bat”中的t,但是不匹配“hate”中的t
例子2:/t$/匹配
“tag at
bat”
中第一行的最后一个t和第二行的t。

4>*:匹配前一个字符0次或多次。
例子:/ab*/匹配“dddabbbbc”中的“abbbb”,也匹配“ddda”中的“a”

5>+:匹配前一个字符1次或多次。
例子:/ab+/匹配“dddabbbbc”中的“abbbb”,但不匹配“ddda”
与后面的{1,}(原型:{n,})的用法类似

6>?:?的用法比较特殊,一般来说它用来对前一个字符做0次或1次匹配,但是它有另外两种特殊的用法:
如果紧跟在*、+、?和{ }之后,则表示原始匹配的最小次数匹配,例如:
/ba*/本来匹配“bbbaaaa”中的“baaaa”,但是/ba*?/则匹配“bbbaaaa”中的“b”(因为*表示0次或多次匹配,而加?应该表示最少次数匹配,即0次匹配)。
同理:/ba+?/则匹配“baaaa”中的“ba”。
作为语法结构符号,使用于前置断言中,即后面要说到的x(?=y)和x(?!=y)

7>.:小数点中的“.”号,匹配任何一个单独的字符,但是换行符除外。
标准中总共有哪些字符?请参考:字符集
例如:/a.b/匹配“acbaa”中的“acb”,但是不匹配“abbb”。

8>(x):表示匹配x(并非特指字符x或者特指一个字符,x表示一个字符串),而且匹配会被记住,在语法中这种()被称为“capturing parentheses ”,即捕捉用的小括号。
匹配会被记住,是因为在表达式提供的函数中,有些函数返回一个数组,该数组会保存所匹配的所有字符串,例如exec()函数。
另外还要注意()中的x被记住的前提是匹配x。
例子1:
var regx=/a(b)c/;
var rs=regx.exec(“abcddd”);
从上面可以看出,/a(b)c/匹配“abcddd”中的“abc”,因为()的原因,b也会记录下来,因此rs返回的数字内容为:
{abc,b}
例子2:
var regx=/a(b)c/;
var rs=regx.exec(“acbcddd”);
rs返回null,因为/a(b)c/不匹配“acbcddd”,所以()中的b不会被记录下来(尽管字符串中含有b)
9>(?:x):匹配x,但不会记住x,这种格式中的()被称为“non-capturing parentheses ”,即非捕捉用的小括号。
例子:
var regx=/a(?:b)c/;
var rs=regx.exec(“abcddd”);
从上面可以看出,/a(?:b)c/匹配“abcddd”中的“abc”,因为(?:)的原因,b不会记录下来,因此rs返回的数字内容为:
{abc}

10>X(?=y):匹配x,仅当后面紧跟着y时。如果符合匹配,则只有x会被记住,y不会被记住。
例子:
var regx=/user(?=name)/;
var rs=regx.exec(“The username is Mary”);
结果:匹配成功,而且rs的值为{user}

11>X(?!y):匹配x,仅当后面不紧跟着y时。如果符合匹配,则只有x会被记住,y不会被记住。
例子:
var regx=/user(?!name)/;
var rs=regx.exec(“The user name is Mary”);
结果:匹配成功,而且rs的值为{user}
例子2:
var regx=/\d+(?!\.)/;
var rs=regx.exec(“54.235”);
结果:匹配成果,rs的值为{5},不匹配54是因为54后面跟着“.”号,当然235也匹配,但是由于exec方法的行为,235不会被返回

12>x|y:匹配x或y。注意如果x和y都匹配上了,那么只记住x。
例子:
var regx=/beijing|shanghai/;
var rs=regx.exec(“I love beijing and shanghai”);
结果:匹配成功,rs的值为{beijing},虽然shanghai也匹配,但不会被记住。

13>{n}:匹配前一个字符的n次出现。
n必须是一个非负数,当然如果是一个负数或小数也不会报语法错误。
例子:
var regx=/ab{2}c/;
var rs=regx.exec(“abbcd”);
结果:匹配成功,rs的值为:{abbc}。

14>{n,}:匹配前一个字符的至少n次出现。
例子:
var regx=/ab{2,}c/;
var rs=regx.exec(“abbcdabbbc”);
结果:匹配成功,rs的值为:{abbc}。注意为什么abbbc也符合条件为什么没有被记住,这与exec方法的行为有关,后面会统一讲解。

15>{n,m}:匹配前一个字符的至少n次最多m次的出现。
只要n与m为数字,而且m>=n就不会报语法错误。
例子:
var regx=/ab{2,5}c/;
var rs=regx.exec(“abbbcd”);
结果:匹配成功,rs的值为:{abbbc}。
例子2:
var regx=/ab{2,2}c/;
var rs=regx.exec(“abbcd”);
结果:匹配成功,rs的值为:{abbc}。
例子3:
var regx=/ab(2,5)/;
var rs=regx.exec(“abbbbbbbbbb”);
结果:匹配成功,rs的值为:{abbbbb},这说明,如果前一个字符出现多于m次,则只匹配m次。另外:
var regx=/ab(2,5)c/;
var rs=regx.exec(“abbbbbbbbbbc”);
结果:匹配失败,rs的值为:null,为什么匹配失败,因为b多于5个则b(2,5)会匹配前5个b,,而表达式/ab(2,5)c/中b后面是c,但字符串中5个b之后还是b所以会报错。

16>[xyz]:xyz表示一个字符串,该模式表示匹配[]中的一个字符,形式上[xyz]等同于[x-z]。
例子:
var regx=/a[bc]d/;
var rs=regx.exec(“abddgg”);
结果:匹配成功,rs的值为:{abd}
例子2:
var regx=/a[bc]d/;
var rs=regx.exec(“abcd”);
结果:匹配失败,rs的值为:null,之所以失败,是因为[bc]表示匹配b或c中的一个,但不会同时匹配。

17>[^xyz]:该模式表示匹配非[]中的一个字符,形式上[^xyz]等同于[^x-z]。
例子:
var regx=/a[^bc]d/;
var rs=regx.exec(“afddgg”);
结果:匹配成功,rs的值为:{afd}
例子2:
var regx=/a[^bc]d/;
var rs=regx.exec(“abd”);
结果:匹配失败,rs的值为:。

18>[\b]:匹配退格键。

19>\b:匹配一个词的边界符,例如空格和换行符等等,当然匹配换行符时,表达式应该附加参数m。
例子:
var regx=/\bc./;
var rs=regx.exec(“Beijing is a beautiful city”);
结果:匹配成功,rs的值为:{ci},注意c前边的空格不会匹配到结果中,即{ ci}是不正确的。

20>\B:代表一个非单词边界。
例子:
var regx=/\Bi./;
var rs=regx.exec(“Beijing is a beautiful city”);
结果:匹配成功,rs的值为:{ij},即匹配了Beijing中的ij。

21>\cX,匹配一个控制字符。例如, \cM 匹配一个 Control-M 或
回车符。 x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一
个原义的 ’c’ 字符。(实际的例子还需补充)

21>\d:匹配一个数字字符,等同于[0-9]。
例子:
var regx=/user\d/;
var rs=regx.exec(“user1”);
结果:匹配成功,rs的值为:{user1}

22>\D:匹配一个非数字字符,等同于[^0-9]。
例子:
var regx=/user\D/;
var rs=regx.exec(“userA”);
结果:匹配成功,rs的值为:{userA}

23>\f:匹配一个换页符。

24>\n:匹配一个换行符。因为是换行符,所以在表达式中要加入m参数。
例子:
var regx=/a\nbc/m;
       var str=“a
               bc”;
       var rs=regx.exec(str);
       结果:匹配成功,rs的值为:{  },如果表达式为/a\n\rbc/,则不会被匹配,因此在一般的编辑器中一个”Enter”键代表着“回车换行”,而非“换行回车”,至少在textarea域中是这样的。      
25>\r:匹配一个回车符

26>\s:匹配一个空格符,等同于[ \f\n\r\t\v\u00A0\u2028\u2029].
例子:
var regx=/\si/;
var rs=regx.exec(“Beijing is a city”);
结果:匹配成功,rs的值为:{ i}

27>\S:匹配一个非空格符,等同于[ ^\f\n\r\t\v\u00A0\u2028\u2029].
例子:
var regx=/\Si/;
var rs=regx.exec(“Beijing is a city”);
结果:匹配成功,rs的值为:{ei}

28>\t:匹配一个tab
例子:
var regx=/a\tb/;
var rs=regx.exec(“a bc”);
结果:匹配成功,rs的值为: {a       bc}

29>\v:匹配一个竖向的tab

30>\w:匹配一个数字、_或字母表字符,即[A-Za-z0-9_ ]。
例子:
var regx=/\w/;
var rs=regx.exec(“$25.23”);
结果:匹配成功,rs的值为:{2}

31>\W:匹配一个非数字、_或字母表字符,即[^A-Za-z0-9_ ]。
例子:
var regx=/\w/;
var rs=regx.exec(“$25.23”);
结果:匹配成功,rs的值为:{$}

32>\n:注意不是\n,这里n是一个正整数,表示匹配第n个()中的字符。
例子:
var regx=/user([,-])group\1role/;
var rs=regx.exec(“user-group-role”);
结果:匹配成功,rs的值为:{user-group-role,-},同样对user,group,role的匹配也是成功的,但像user-group,role等就不对了。

33>\0:匹配一个NUL字符。

34>\xhh:匹配一个由两位16进制数字所表达的字符。

35>\uhhhh:匹配一个由四位16进制数字所表达的字符。

3,表达式操作

1)表达式操作,在这里是指和表达式相关的方法,我们将介绍六个方法。
2)表达式对象(RegExp)方法:

1>exec(str),返回str中与表达式相匹配的第一个字符串,而且以数组的形式表现,当然如果表达式中含有捕捉用的小括号,则返回的数组中也可能含有()中的匹配字符串,例如:
var regx=/\d+/;
var rs=regx.exec(“3432ddf53”);
返回的rs值为:{3432}
var regx2=new RegExp(“ab(\d+)c”);
var rs2=regx2.exec(“ab234c44”);
返回的rs值为:{ab234c,234}
另外,如果有多个合适的匹配,则第一次执行exec返回一个第一个匹配,此时继续执行exec,则依次返回第二个第三个匹配。例如:
var regx=/user\d/g;
var rs=regx.exec(“ddduser1dsfuser2dd”);
var rs1=regx.exec(“ddduser1dsfuser2dd”);
则rs的值为{user1},rs的值为{rs2},当然注意regx中的g参数是必须的,否则无论exec执行多少次,都返回第一个匹配。后面还有相关内容涉及到对此想象的解释。

2>test(str),判断字符串str是否匹配表达式,返回一个布尔值。例如:
var regx=/user\d+/g;
var flag=regx.test(“user12dd”);
flag的值为true。

3)String对象方法

1>match(expr),返回与expr相匹配的一个字符串数组,如果没有加参数g,则返回第一个匹配,加入参数g则返回所有的匹配
例子:
var regx=/user\d/g;
var str=“user13userddduser345”;
var rs=str.match(regx);
rs的值为:{user1,user3}

2>search(expr),返回字符串中与expr相匹配的第一个匹配的index值。
例子:
var regx=/user\d/g;
var str=“user13userddduser345”;
var rs=str.search(regx);
rs的值为:0

3>replace(expr,str),将字符串中匹配expr的部分替换为str。另外在replace方法中,str中可以含有一种变量符号$,格式为$n,代表匹配中被记住的第n的匹配字符串(注意小括号可以记忆匹配)。
例子:
var regx=/user\d/g;
var str=“user13userddduser345”;
var rs=str.replace(regx,”00”);
rs的值为:003userddd0045
例子2:
var regx=/u(se)r\d/g;
var str=“user13userddduser345”;
var rs=str.replace(regx,”$1”);
rs的值为:se3userdddse45
对于replace(expr,str)方法还要特别注意一点,如果expr是一个表达式对象则会进行全局替换(此时表达式必须附加参数g,否则也只是替换第一个匹配),如果expr是一个字符串对象,则只会替换第一个匹配的部分,例如:
var regx=“user”
var str=“user13userddduser345”;
var rs=str.replace(regx,”00”);
rs的值为: 0013userddduser345

4>split(expr),将字符串以匹配expr的部分做分割,返回一个数组,而且表达式是否附加参数g都没有关系,结果是一样的。
例子:
var regx=/user\d/g;
var str=“user13userddduser345”;
var rs=str.split(regx);
rs的值为:{3userddd,45}

4,表达式相关属性

1)表达式相关属性,是指和表达式相关的属性,如下面的形式:
var regx=/myexpr/;
var rs=regx.exec(str);
其中,和表达式自身regx相关的属性有两个,和表达式匹配结果rs相关的属性有三个,下面将逐一介绍。
2)和表达式自身相关的两个属性:

1>lastIndex,返回开始下一个匹配的位置,注意必须是全局匹配(表达式中带有g参数)时,lastIndex才会有不断返回下一个匹配值,否则该值为总是返回第一个下一个匹配位置,例如:
var regx=/user\d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex1=regx.lastIndex;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex2=regx.lastIndex;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex3=regx.lastIndex;
上面lastIndex1为9,第二个lastIndex2也为9,第三个也是9;如果regx=/user\d/g,则第一个为9,第二个为18,第三个为0。

2>source,返回表达式字符串自身。例如:
var regx=/user\d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var source=regx.source;
source的值为user\d
3)和匹配结果相关的三个属性:

1>index,返回当前匹配的位置。例如:
var regx=/user\d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var index1=rs.index;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var index2=rs.index;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var index3=rs.index;
index1为4,index2为4,index3为4,如果表达式加入参数g,则index1为4,index2为13,index3会报错(index为空或不是对象)。

2>input,用于匹配的字符串。例如:
var regx=/user\d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var input=rs.input;
input的值为sdsfuser1dfsfuser2。

3>[0],返回匹配结果中的第一个匹配值,对于match而言可能返回一个多值的数字,则除了[0]外,还可以取[1]、[2]等等。例如:
var regx=/user\d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var value1=rs[0];
rs=regx.exec(“sdsfuser1dfsfuser2”);
var value2=rs[0];
value1的值为user1,value2的值为user2

5,实际应用

1)实际应用一
描述:有一表单,其中有一个“用户名”input域
要求:汉字,而且不能少于2个汉字,不能多于4个汉字。
实现:
<script>
function checkForm(obj){
     var username=obj.username.value;
     var regx=/^[\u4e00-\u9fa5]{2,4}$/g
     if(!regx.test(username)){
               alert(“Invalid username!”);
               return false;
     }
     return true;
}
</script>
<form name=“myForm”onSubmit=“return checkForm(this)”>
    <input type=“text” name=“username”/>
    <input type=“submit” vlaue=“submit”/>
</form>
2)实际应用二
描述:给定一个含有html标记的字符串,要求将其中的html标记去掉。
实现:
<script>
function toPlainText(htmlStr){
     var regx=/<[^>]*>|<\/[^>]*>/gm;
     var str=htmlStr.replace(regx,"");
     return str;
}
</script>
<form name=“myForm”>
    <textarea id=“htmlInput”></textarea>
    <input type=“button” value=“submit” onclick=“toPlainText(document.getElementById(‘htmlInput’).value”/>
</form>

三,小结

1,Javascript正则表达式,我想在一般的程序员之中,使用者应该不是很多,因为我们处理的页面一般都不是很复杂,而复杂的逻辑一般我们都在后台处理完成了。但是目前趋势已经出现了扭转,富客户端已经被越来越多的人接受,而Javascript就是其中的关键技术,对于复杂的客户端逻辑而言,正则表达式的作用也是很关键的,同时它也是Javascript高手必须要掌握的重要技术之一。

2,为了能够便于大家对前面讲述的内容有一个更为综合和深刻的认识,我将前面的一些关键点和容易犯糊涂的地方再系统总结一下,这部分很关键!
总结1:附件参数g的用法
表达式加上参数g之后,表明可以进行全局匹配,注意这里“可以”的含义。我们详细叙述:
1)对于表达式对象的exec方法,不加入g,则只返回第一个匹配,无论执行多少次均是如此,如果加入g,则第一次执行也返回第一个匹配,再执行返回第二个匹配,依次类推。例如
var regx=/user\d/;
var str=“user18dsdfuser2dsfsd”;
var rs=regx.exec(str);//此时rs的值为{user1}
var rs2=regx.exec(str);//此时rs的值依然为{user1}
如果regx=/user\d/g;则rs的值为{user1},rs2的值为{user2}
通过这个例子说明:对于exec方法,表达式加入了g,并不是说执行exec方法就可以返回所有的匹配,而是说加入了g之后,我可以通过某种方式得到所有的匹配,这里的“方式”对于exec而言,就是依次执行这个方法即可。
2)对于表达式对象的test方法,加入g于不加上g没有什么区别。
3)对于String对象的match方法,不加入g,也只是返回第一个匹配,一直执行match方法也总是返回第一个匹配,加入g,则一次返回所有的匹配(注意这与表达式对象的exec方法不同,对于exec而言,表达式即使加上了g,也不会一次返回所有的匹配)。例如:
var regx=/user\d/;
var str=“user1sdfsffuser2dfsdf”;
var rs=str.match(regx);//此时rs的值为{user1}
var rs2=str.match(regx);//此时rs的值依然为{user1}
如果regx=/user\d/g,则rs的值为{user1,user2},rs2的值也为{user1,user2}
4)对于String对象的replace方法,表达式不加入g,则只替换第一个匹配,如果加入g,则替换所有匹配。(开头的三道测试题能很好的说明这一点)
5)对于String对象的split方法,加上g与不加g是一样的,即:
var sep=/user\d/;
var array=“user1dfsfuser2dfsf”.split(sep);
则array的值为{dfsf, dfsf}
此时sep=/user\d/g,返回值是一样的。
6)对于String对象的search方法,加不加g也是一样的。
总结2:附加参数m的用法
附加参数m,表明可以进行多行匹配,但是这个只有当使用^和$模式时才会起作用,在其他的模式中,加不加入m都可以进行多行匹配(其实说多行的字符串也是一个普通字符串),我们举例说明这一点
1)使用^的例子
var regx=/^b./g;
var str=“bd76 dfsdf
         sdfsdfs dffs
         b76dsf  sdfsdf”;
var rs=str.match(regx);
此时加入g和不加入g,都只返回第一个匹配{bd},如果regx=/^b./gm,则返回所有的匹配{bd,b7},注意如果regx=/^b./m,则也只返回第一个匹配。所以,加入m表明可以进行多行匹配,加入g表明可以进行全局匹配,综合到一起就是可以进行多行全局匹配
2)使用其他模式的例子,例如
var regx=/user\d/;
var str=“sdfsfsdfsdf
         sdfsuser3 dffs
         b76dsf  user6”;
var rs=str.match(regx);
此时不加参数g,则返回{user3},加入参数g返回{user3,user6},加不加入m对此没有影响。
3)因此对于m我们要清楚它的使用,记住它只对^和$模式起作用,在这两种模式中,m的作用为:如果不加入m,则只能在第一行进行匹配,如果加入m则可以在所有的行进行匹配。我们再看一个^的例子
var regx=/^b./;
var str=“ret76 dfsdf
         bjfsdfs dffs
         b76dsf  sdfsdf”;
var rs=str.match(regx);
此时rs的值为null,如果加入g,rs的值仍然为null,如果加入m,则rs的值为{bj}(也就是说,在第一行没有找到匹配,因为有参数m,所以可以继续去下面的行去找是否有匹配),如果m和g都加上,则返回{bj,b7}(只加m不加g说明,可以去多行进行匹配,但是找到一个匹配后就返回,加入g 表明将多行中所有的匹配返回,当然对于match方法是如此,对于exec呢,则需要执行多次才能依次返回)
总结3:在HTML的textarea输入域中,按一个Enter键,对应的控制字符为“\r\n”,即“回车换行”,而不是“\n\r”,即“换行回车”,我们看一个前面我们举过的例子:
var regx=/a\r\nbc/;
var str=“a
         bc”;
var rs=regx.exec(str);
结果:匹配成功,rs的值为:{      },如果表达式为/a\n\rbc/,则不会被匹配,因此在一般的编辑器中一个”Enter”键代表着“回车换行”,而非“换行回车”,至少在textarea域中是这样的。

四,应用案例

1,正则表达式使用场景:
1)登录场景,检查用户输入的用户名,要求:
字符长度在6到18之间
字符必须为字母、数字或者下划线的组合
2)购物场景,对于商品列表的描述(标签、条形码、单价)等有些用户可能会提出下面需求:
希望可以对商品列表的某一列描述进行字号的自定义,而且下次登录仍然保持用户的修改
2,下面看一下在上述两个场景中,正则表达式的使用方式和具体实现。
1)登录场景部分正则表达式实现

2)购物场景部分正则表达式实现
1>需求分析:用户希望可以对商品列表的某一列描述进行字号的自定义,而且下次登录仍然保持用户的修改

2>程序设计

类图:

3>代码实现
PageSetting类

PageSettingParser类

注:如果需要上面的应用案例的工程,请发email给我。

http://www.phpv.net/html/1534.html

2008年8月11日

十大轻量级的Linux发行版

今天在一个叫Lightweight Linux的博客上看到了这一篇《十大轻量级的Linux发行版》的文章,个人觉得写得不错,于是就把它翻译成中文,和各位喜欢轻量级发行版的朋友分享一下。在这篇文章里,我会向大家介绍十个最有用而且大家也都很熟悉的轻量级Linux发行版。其中有八个本来就是轻量级的,而且对计算机的配置要求也不高;最后的两个可以通过自已的定制安装来实现轻量级系统。

在这篇文章里,我不会详细的介绍每一个轻量级的发行版,因为我打算在深入地了解了它们之后再写一份详细的报告。在接下来的几个月里,我会把它们安装到我的一台计算机中。在过去的七年里,作为我的主桌面系统,它们是我使用得最多的操作系统。我相信,深入地去了解它们这几年所发展历史将会是一件有趣的事情。

首先出场的四个迷你发行版:

Damn Small Linux DSL是一个非常体积小的发行版。它是一个50M大小的LiveCD,也能安装到硬盘上。DSL能完全的在RAM里运行,而且你可以通过软件仓库为它安装更多的软件。DSL的推荐配置是P200和64MB内存。

Puppy Linux 也是以Live CD的开式发行,它运行的最低内存要求可以达到32M,并且它的启动速度很快,一般都能在60秒内完成启动。Puppy Linux的目标是打造一个易用的系统,不需要太多技术方面的要求。

Feather Linux 是一个大小为128M的发行版,与DSL一样,它也是基于knoppix(knoppix是基于Debian Linux)定制而成的,它集成了人们日常的常用工具。

DeLi(DeLi Linux 表示 “Desktop Light” Linux)它是一个针对老计算机的发行版,支持从 486 到 Pentium III 或类似的计算机。专注于桌面用途,包括:电子邮件客户端、图形界面的网页浏览器、办公软件(文字处理、电子表格)等等。包括了 Xorg 和开发工具的完全安装不会需要超过750 MB 的硬盘空间。

在接下来的四个可以说是中型发行版了:

Vector Vector Linux Standard GOLD是一个完全免费下载的发行版,它包括了各种软件。Vector Linux是一下基于Slackware,而专门为低配置的老计算机设计的。在一台只有Pentium 200、128内存以及3G硬盘空间的老机器上高效的运行。在即将发行的VL Light完全安装只需要350M的空间以及64M的内存来运行。

Zenwalk是另一个基于Slackware的发行版,它追求的是轻便、快速,并没有过多的软件。虽然它以i686为标准,但也是完全兼容i486的。Zenwalk的配置要求是 Pentium III处理器、128M内存和2G的硬盘空间。

Antix 是一个基于Mepis定制的轻量级系统。Antix的最低配置要求是P266处理器和64M的内存。由于antiX-M7采用的i686的内核,所以不能在一些旧的处理器上运行了,如Pentium I, AMD K5, AMD K6…

PClos TinyME是一个基于PCLinuxOS定制的系统。它集成了Abiword、Opera浏览器、Audacious音乐播放器以及Sylpheed邮件客户端等程序。TinyME的配置要求是Pentium处理器、64M的内存。

接下来的两个可以通过定制来安装来打造自己的轻量级系统:

Debian 是一个 自 由的操作系统 (OS) 供您和您的计算机使用。一个操作系统就是让您的计算机工作的一系列基础程序和实用工具的集合。由于Debian采用了Linux 内核(一个操作系统的核心),但是大部分基础的操作系统工具都来源于GNU项目,因此又称之为GNU/Linux。

Slackware Linux是由Patrick Volkerding开发的GNU/Linux发行版。与很多其他的发行版不同,它坚持KISS(Keep It Simple Stupid)的原则,就是说没有任何配置系统的图形界面工具。一开始,配置系统会有一些困难,但是更有经验的用户会喜欢这种方式的透明性和灵活性。

当然,轻量级的Linux发行版还有很多很多,如ttylinux、SLAX、CD Linux等。这十大轻量级也是作者自己评出来的,或许你认为有更好的轻量Linux,不过还是要谢谢作者与我们分享了他对轻量级Linux的看法。现在的U盘容量都那么大,选一个自己喜欢的轻量级Linux装到U盘里也是一个不错的选择。

2008年7月27日

10个来自国外的优秀免费发送短信的站点

如今国内的用户对于手机资费的抱怨还是一直存在的,且不说双向收费这样的老大难问题,单就通话或短信的资费来讲我们的标准也都存在普遍较高的问题,虽然国家已经多次召开资费标准听证会,而我们也确实见到了一些下调,不过进度仍旧是缓慢的,这时就有了一种省钱的新模式,那就是通过互联网来向手机端发送免费短信,虽然可能会有些麻烦,但它的实际意义还是有的,毕竟我们节省了自己的花费,下面我们就为大家介绍10个来自国外的优秀免费发送短信的站点,一起来看看吧!

1、Bloove.com 可以将你的手机内的联系人上传到站里,登陆之后就可以直接准确的将短信息发送到他们的手机上,非常方便快捷。
2、ClearSMS.com 一个专业级的商用信息收发以及大规模群发的站点,它可以为你的用户提供不同的受到讯息提示,另外也可以通过付费来享受到更多的信息定制服务。
3、GizmoSMS.com GizmoSMS可以让你免费自如的像全世界超过50个国家的用户发送免费短信,只是它并不能发送彩信,和其他任何多媒体消息,当然免费的我们还有什么可以挑剔的呢。
4、Group2Call.com 支持导入你的本地联系人名单,然后可以以你自己设定好的群组进行免费短信群发,另外值得高兴的是它支持将声音文件一同发出,这是许多免费服务所没有的。
5、Jaxtr.com 这个有点像一个当今流行的桌面“微件”,虽然看起来小,但是他也同样能够满足我们的免费短信需要,支持超过38个国家间的免费短信发送。
6、OhDontForget.com 这个站与其他的站功能基本相同,不过它的亮点在于可以设定信息发送的时间,用来有特定需要的发送。
7、SMSGupShup.com 一个非常强大的信息发送站点,支持向最多5000人群发短信,不知道这里会不会成为垃圾短信的源头...当然我们一般人也很难有5000个联系人。
8、Swaggle.mobi 目前支持iPhone做好的免费短信发送站,支持iPhone上的联系人名单,并可以按组群发。
9、Yahoo Mobile Yahoo推出的免费信息发送服务,当然它也不单单有这一项业务,而且是免费于收费并存的模式,不过对于它功能的强大与否是我们完全可以放心的。
10、Yellowpipe 基于网页的一个免费短信与网络电话相结合的站点,我们除了可以发送短信之外还可以拨打通信录上的电话,并且方便的进行免费回拨。

2008年6月9日

文檔 格式轉換

現在的檔格式真是過於繁多,就我而言,從96年接觸,不能說很精通,也說得過去,但看到現在繁多的檔格式也是十分頭疼。有時發現一個不錯的檔不能打開也是望而興歎!web2.0時代的檔轉換器能幫我們解決這個問題! 檔轉換器是非常具有實用價值的線上工具,它可以將一些陌生的檔格式轉變為我們熟悉或喜歡的格式,以符合我們的習慣。不知道大家用得多不多,反正我經常會使用,主要是用在文檔檔格式轉換、媒體檔轉換,省去好多安裝不同軟體的麻煩。以下推薦若干個我所知道的檔轉換器,可能不是很全,但有這些一般的使用應該綽綽有餘了。
clip_image001
1、通用類:
clip_image002zamzar 是一個很牛的線上轉換工具,能轉換100M以下的到40種格式的檔,包括圖像格式、文檔格式、音頻格式、視頻格式等,幾乎囊括了我們熟知的所有檔格式,可以自由轉換,功能相當不錯的了,可以說是一個比較全能的工具了,而且頁面簡潔易用,速度也很不錯!!(via
clip_image003Youconvertit 提供堪稱最完美的線上檔轉換服務,能線上對文檔、圖片、音頻以及視頻檔進行轉換。能在41種文檔格式(常用如html,txt,ppt,doc, pdf,rtf,csv,psd,xls,xhtml,xls等)、85種圖片格式(常用如bmp,jpg,gif,tiff,ico,png等)、7種 音頻格式(aac、aif、aiff、mp3、ra、wav、wma)、11種視頻格式(3gp、asf、avi、flv、mov、mp4、mpeg、 mpg、rm、swf、wmv)進行相互轉換。實在是一項非常不錯的服務。(via
clip_image004Xurrency 是線上的當前貨幣兌換查詢工具,介面非常簡單,選擇幣種,輸入金額即可快速獲得目標幣種的數額。同時,底部還有一個即時的匯率表,直觀的回饋一些主要幣種的現時匯率。放在此類有些牽強,對一些朋友會很有用。
2、媒體類
clip_image005Fivix 是一個視頻轉換的平臺,可將YouTube、Google Video等視頻網站的視頻轉化格式、或直接生成下載鏈結,用戶可將視頻檔根據需要隨意轉化為avi、mov、3gp、mp4、mp3格式,並生成下載。(詳情
clip_image006Movavi 是全綠色版本,不需要你註冊、下載、安裝等等繁瑣,任何人進入網站就能直接使用。使用大致分為三步,在一頁內均能完成。允許你將本地電腦、或者網路中的視頻檔進行格式的轉換,生成你所喜歡的media檔。並提供了轉換工具下載及博客掛件,方便你的使用。(詳情
clip_image007Converttube 可將Youtube視頻檔進行轉換並提供下載,最近更是添加了mobile檔的支持,一共可轉換為6種格式:mpg、flv、mov、mp3、3gp、mp4。
clip_image008與Converttube 幾乎一樣,Vconvert 又是一個線上視頻轉換工具,可將YouTube等視頻共用網站的檔轉換為wmv, mov, mp4, mp3, 3gp等。
clip_image009SpinVox 提供語音到短信業務,出發點是為了方便用戶隨時掌握自己的留言,註冊為用戶後,網站會自動將你的語音留言轉為文本短信,並及時的發送到你的手機、郵箱或博客上,用戶不用上網,而利用手機就可以收發SpinVox 資訊,同任何SpinVox 用戶進行通信,而且可以支持任何手機,無需下載新的軟體。但是,目前針對英語、西班牙語、法語和德語用戶。(詳情
clip_image010Vozme 更為簡單和實用,不需要註冊就能使用所有功能。這次推薦的是英文版本,你只需要在對話方塊內輸入想要說的話(英文),點擊創建mp3,在短短進分鐘內立刻就 能生成mp3檔。速度還是很快的,製作完成後提供線上播放和檔下載。同時網站還提供了掛件代碼,貼在博客上可隨時使用。(詳情
clip_image011Filsh 提供線上下載視頻網站的視頻檔的服務,並且還支援對檔格式的轉換,能將檔轉換成如下格式: .mpg .avi .mov .3gp .mp4 .flv .mp3 .ogg,同時還可以對碼率以及視頻尺寸進行設置。功能已經是很強大的了,而且下載及轉換的速度也還比較理想,不過不支援本地檔的轉換,只能轉換網路上 的一些檔。(via
clip_image012Flvto 是很簡單的一個線上轉換器,可以將Youtube視頻轉變為mp3格式,或者將你本地的視頻(flv格式)轉變為mp3檔。根據你提供的視頻檔大小需要等待不同的時間,不過速度還算可以。轉換後提供下載的網址,或者可以直接發佈到你的社會化網路服務上。(詳情

3
、文檔類
clip_image013pdfonline 功能最為強大的PDF線上工具集合,很奇怪國內用戶很少人用。我以前也沒怎麼用過,這次整理時才發現,包括了一些很實用的工具,值得慢慢挖掘。其中pdf 檔轉化工具更是讓我眼前一亮,也是目前我所發現支持檔格式最多的一個工具,包括MS Word (DOC | RTF) 、MS PowerPoint (PPT)、MS Publisher (PUB)、MS Excel (XLS) 、HTML (MHT)、Text (TXT) 、JPG、GIF、TIFF、BMP、PNG、EMF、WMF。
clip_image014KoolWire 也是一個線上PDF轉換工具,但其操作方法有所不同,用戶只需把想要轉換的文檔發送Email到 pdf@koolwire.com 郵箱中就OK了,過一段時間就會收到轉換好的PDF檔了。目前KoolWire 支持Word (.doc), Powerpoint (.ppt), Excel (.xls), Jpeg, GIF, Rich Text Format (.rtf), TXT等格式的文檔,並且完全支持中文。(引自
clip_image015Readthewords 是一款全能的線上將文本(文檔)轉換成語音的服務,可以將文本(文檔)包括HTML以及RSS/Feed轉換成語音檔並提供下載。在 readthewords可以直接輸入一段文字進行轉換,也可以上傳PDF 、Word、HTML 三種格式的檔進行轉換,不僅如此,你可以直接輸入web/RSS Feeds 位址,readthewords能將組成該web/RSS Feeds 的每一個網頁或者blog文章轉換成單獨的MP3檔。提供了14種語音,分別來自14個不同性別不同年齡的閱讀者。(via
clip_image016Yakitome 又一個功能強大的線上轉換文本成語音(Text To Speech)的服務,支援將English,Spanish,French,German四種語言的文字以及.doc .pdf .txt .html.xml等格式的文檔轉換成mp3.wav格式。(via
clip_image017Pdfmenot是一個提供線上文檔轉換服務的網站,可以將PDF檔轉換成Flash格式。你可以將網頁上的PDF檔鏈結,或者本地的PDF檔直接上傳到Pdfmenot即可進行轉換。轉換後的Flash格式的內容,你可以通過鏈結 或者Js代碼將其放置在你的網站或者Blog上面進行分享。這樣也就提供了一種在你網站上面分享PDF檔的方式。(via
4、圖像類
clip_image018Gickr 一個線上的綠色版小工具,你可以不需註冊就能直接製作精美的GIF格式圖片,享受動畫的快感!幾乎與一些專業的gif製作軟體相似,可以用任意的幾張圖片進行組合,達到動畫的效果,甚至支援用youtube的視頻直接轉換成gif圖片。(詳情
clip_image019 Make3d 很有意思的一個線上工具,你上傳照片後,Make3d 可根據你照片的場景,由二維變為三維。不過你上傳的圖片必須是連續的一組圖片,現在大多的數碼相機都有360度拍攝功能。Make3d 採用了類似立體電影的技術,在視覺上給你3D的感受。
clip_image020Fotowoosh 可以讓你在一張2D的圖片上產生3D的錯覺效果,它可以通過一定的技術將你上傳上去的 2D 平面圖片輕鬆轉換成 3D 的效果;該技術由全球著名的免費空間服務商Freewebs提供。(via
clip_image021Vectormagic 線上點陣圖轉向量圖工具,可幫你輕鬆修復邊緣的鋸齒,讓圖片邊緣更圓滑。大家都知道,我們通常作的圖都是點陣圖,放大後會失真,邊緣出現難看的鋸齒,而向量圖放大後邊緣不變,一樣的圓滑。其實,Vectormagic 也正是將你的圖片轉變為向量圖,從而使圖片的品質大大提高!(詳情
clip_image022Convertico 可實現線上PNG與ICO兩種圖片格式的互換,無須安裝任何軟體,簡單而實用。
clip_image023Photo2Text是一個提供將圖片轉化成文字圖片服務的網站。只需上傳你想要轉換的圖片即可。轉換的圖片可以通過下載,也可以生成專有的鏈結來查看。(via
原文:http://enjoyweb20.cn/index.php/2008/06/fileconvertlist/