2008年9月24日

小野豬竄過馬路頭夾鐵欄

屯門青山公路昨上演失魂小野豬亂闖馬路被困鐵欄意外。一頭兩歲小野豬疑與父母失散走出馬路,在車輛撞來之際拔足逃命,豈料豬頭卻遭路中石壆鐵欄緊夾,小豬哀鳴大叫;三小時後由獸醫注射麻醉藥,呼呼大睡輕易被救出。
遇險小野豬屬雄性,兩歲大,重達80斤,其間孔武有力的小野豬嘗試猛力掙扎逃走,反令頸部磨擦受傷流血,事後需數名漁護署人員合力,才能將牠抬上獸籠送往上水狗房,待傷癒放生讓其回歸大自然。
發生鐵欄夾野豬的青山公路路段位於屯門藍地盈溢居對開,上址車來車往附近亦有輕鐵站,交通十分繁忙。大埔狩獵野豬隊隊長楊佳權稱,現場靠近大欖郊野公園是野豬出沒地點,今次野豬衝出馬路事件幸未釀交通意外,值得關注。

clip_image001

消防員用壓力剪迫開鐵欄,成功救出已麻醉了的小野豬。周志鴻攝

clip_image002

重達80斤的小野豬獲救後,由數名漁護署人員合力抬走。

5分鐘注射兩麻醉針

現場消息稱,昨晨約7時,小野豬疑與父母由山上下來覓食,其間小豬好奇四處走失散,竟慌不擇路走出青山公路南行線,據知來往車輛的司機目睹小豬步出馬路,爭相扭clip_image003閃避及響號,小野豬嚇得在路中亂竄40米。
其間失魂小野豬欲衝過對面馬路逃命,結果反遭分隔於路中的鐵欄所夾,現場所見,野豬粗壯豬頸正好夾在鐵欄的4吋空隙中,當場動彈不得。消防員接報到場,為怕野豬遭來往車輛聲浪驚嚇亂走,用黑布蓋clip_image004豬頭,並以繩索綁緊豬腿嘗試救出,可是野豬拚命掙扎反越夾越緊,只好求助漁護署。
兩小時後,漁護署獸醫到來審視現場環境,發現野豬稍為安靜,小心翼翼走近,5分鐘內從野豬後腿注射兩支麻醉針,獸醫靜待數分鐘確定麻醉藥發作,野豬呼呼大睡,消防員便取壓力剪迫開鐵欄,成功救出小野豬。

clip_image005

小野豬頭部夾於鐵欄間動彈不得,在路中哀鳴。

2008年9月8日

最坚挺上海楼市出现跳楼价 最高每平米下跌8500元

最坚挺上海楼市出现跳楼价 最高每平米下跌8500元

新闻来源: 新华网 于August 28, 2008 04:11:51

全国楼市降声一片,上海也不例外。

“热烈庆祝房价下降。太好了。”8月22日,有上海市民在论坛里表示。此前一天,全国多家媒体同时报道了上海市中心某楼盘每平方米狂降7000元的消息。
作为全国最坚挺的楼市,上海也未能避免房价出现“跳水”。

“早在一个多月前,我就注意到了上海房价出现下降。”夏航是上海某集团公司高管,在上海、北京等地从事房地产收购业务,最近几个月,接触了很多资金紧张的开发商。在夏先生看来,眼下楼市就是一场博弈。

“未来房价走势,要看谁挺得住,如果开发商挺不住,房价就会降。”房地产界普遍担心的问题在于,“房价越降,老百姓越不买房。”

惊现“跳楼价”

上周,一直被认为保值升值功能最好的上海市中心楼盘,成了房价下跌的领头羊。

来自上海佑威房地产研究中心的最新报告显示,8月18日,上海中远两湾城的29套房源集中成交,均价13842元/平方米,比上半年21049元/平方米跌了7200多元/平方米!

无独有偶,大华锦绣华城8月拿出1、2号楼促销,成交的61套房源均价13551元/平方米,其中5套特价房均价12079元/平方米,比上半年 17740元/平方米的均价,跌幅达5600多元/平方米!这与近日当地两地产巨头万科、金地之间备受关注的价格战相比,有过之而无不及。

在调查中中国经济时报记者了解到,去年初,报价仅每平方米13000元的中远两湾城,今年2月价格曾高达23000元。其均价从去年初的 13030元一路涨到今年3月的最高点22336元,涨幅高达71%,不过成交量却一路下滑。7月初,尽管中远两湾城首次在当地媒体打出9折广告,售价大幅下降了3000多元,但销售业绩仍不理想。当地业界人士认为,这也是其选择进一步降价的原因。

进入8月,中远两湾城降价幅度明显扩大,至8月21日,成交的34套房源每平方米均价仅14001元,引人关注的是,其中8月18日集中成交的 29套房源均价仅13842元,8月21日成交的三套更是低至13804元,相比最高点的3月份价格已经跌去8532元,跌幅高达40%。

同样,作为当地超级大盘的大华锦绣华城,去年初均价涨到10000元,今年初最高达到19000元,如今回落到了12079元的价位。

除以上两个楼盘外,万科金色雅筑、阳城贵都等这些近期领跌的楼盘无一例外都位于上海目前居住氛围最成熟的内中环区域,而远中风华园、上海滩新昌城、君御豪庭等上海中心区的楼盘近期也都出现了下跌现象。

从去年10月开始,全国楼市开始降温,上海一直是楼市这轮调整中最坚挺的城市。今年上半年,上海一手商品公寓平均成交价格四环五区(内环内、内中环、中外环、外郊环和外环外)涨幅,同比分别高达76%、84%、48%、45%和30%,中环区域的三林、高桥、大宁、大华、万里等板块楼盘的涨幅都超过或接近一倍。可这种势头并没有得到延续。进入下半年以来,楼市引发连锁反应,上海楼盘降价风暴不断出现。

专家:阴跌刚刚开始

事实上,在上海,无论是中远两湾城还是大华锦绣华城,都不是当地率先领跌的楼盘,真正嗅出楼市变化并果断采取有效促销手段的地产巨头,非和记黄埔莫属。早在6月初,一则御翠豪庭跌价万元的新闻就曾引起上海楼市巨大波动。在成功回笼10亿元资金之后,李嘉诚旗下的别墅项目御翠豪庭每平方米售价重又调高了1 万余元。

受深圳、广东房价下跌影响的上海楼市,新房开始频频出现95折以上的折扣,二手房更是降价频频。事过境迁,当楼市再次出现大幅降价时,消费者并未踊跃买单。

“世上没有只涨不跌的东西,就像股市一样,涨得过高了,很自然就会跌下来。”谈到当地房价时一位上海市民说。随着楼市成交一再萎缩,购房者观望气氛日渐浓厚。“房价太高。”“挺住,都别买房。”“不降到合理的价位,绝不买房。”上海部分市民近日在互联网论坛里相互打气。

受购房者观望影响,预期每平方米报价17000元的春申丽园,最终开盘价只有15000元,已成交的22套房源均价更是只有14000多元;每平方米报价15000元金地格林风范城实际售价只有12000多元。最近,宝山罗店的美兰湖颐景园最低折扣甚至打到了8折。另外以特价房、送车、送装修、奥运金牌优惠等各种名义打折的楼盘不在少数。

不过,除万科金色雅苑、大华阳城贵都、大华锦锦绣华城、大华颐和华城、摩卡小城等实际价格下调10%以上的楼盘,有较好的成交业绩外,多数打9.5折以内的促销楼盘无人问津。

佑威房地产研究中心主任薛建雄认为,在房地产业走向成熟产品快速升级和宏观经济走向不明朗的情况下,目前市场上楼盘无量空守的风险巨大。他说,房地产业经过十年高速成长,已进入成熟期,房价过快上涨带来的暴利将难已重现,能够开发出越来越好的产品来改善国人居住条件的开发商,才可能会有良好的生存和发展空间。

一直被视为楼市风向标的上海豪宅市场,最近也出现了价格松动迹象。薛建雄认为,作为上海房价标杆的豪宅价格一旦下跌,上海房价的全面性下跌也会来临。“由于上海楼市的购买潜力依然巨大,多数在售楼盘的跌幅应该只会在10%-30%之间。”不过他同时表示,“上海楼市的阴跌可能只是刚刚开始。”

海南三亚将建全球第二家七星级酒店 2011年开业

海南三亚将建全球第二家七星级酒店 2011年开业(图)

新闻来源: 京华时报 于September 07, 2008 18:23:58

海南三亚将建全球第二家七星级酒店,这也是继阿联酋迪拜“帆船酒店”后,全球第二家七星级酒店。酒店占地323亩,毗邻豪华游艇俱乐部和亚洲最大的海洋公园。

海棠湾美景
阿联酋迪拜“帆船酒店”

9月8日报道 前天,今典集团与有百年历史的费尔蒙酒店集团在三亚签署国内首个七星级酒店“红树林费尔蒙酒店”的委托管理协议,这也是继阿联酋迪拜“帆船酒店”后,全球第二家七星级酒店。

据了解,“红树林费尔蒙酒店”位于三亚海棠湾,由海南省政府批准规划,定位为“国家海岸”,总面积约150平方公里。酒店位于海棠湾的中心区域,占地323 亩,毗邻一个豪华游艇俱乐部、一座27洞的海滨高尔夫球场和亚洲最大的海洋公园。与周围20个五星级酒店形成豪华度假旅游带。

今典集团董事长张宝全表示,与费尔蒙的合作将不涉及资金投入。“红树林费尔蒙”酒店的建设,今典集团将投资15亿至20亿元,年内开工,2011年全面开业。酒店设计将由设计帆船酒店的阿尔金斯及世界顶尖设计公司来承担。

2008年9月4日

长洲岛-鱼珠要建过江隧道 改善长洲岛出行

北接茅岗路南接金洲大道,总长3057米隧道长1480米

image

制图/陈春鸣

本报讯 记者许琛、通讯员刘国贤报道:长洲岛上有著名的黄埔军校旧址,又将建辛亥革命纪念馆,但长期

以来,与周边地区主要依靠渡轮方式往来,交通落后。近日,广州市政府在答复省政协委员提案时表示,长洲-鱼珠过江隧道最终规划方案已定,计划今年年底前完成前期研究工作和前期报批手续。

省政协委员温良在提案中指出,长期以来,长洲岛与周边地区仅仅依靠轮渡方式往来,落后的交通方式已极大地阻碍了长洲的发展,对其岛上的旅游资源造成巨大的浪费。

广州市政府在答复中表示,目前具有重要历史与现实意义的辛亥革命纪念馆的选址已确定在长洲岛中山公园旁,建成后将与黄埔军校等景点连成一片,成为广州市旅游文化的一大亮点。因此该项目的建设对改善长洲岛和黄埔区的交通条件具有重要意义,对长洲岛的经济文化和旅游事业的发展有重要作用。

目前已拟定完善了长洲-鱼珠过江隧道最终规划方案,正在进行深化。隧道北接茅岗路,南接金洲大道,总长度约3057米,隧道长度1480米。计划2008年年底前完成前期研究工作和前期报批手续,初步稳定设计方案。待条件成熟后,将根据城建资金情况及早安排实施。

2008年9月2日

城内私密地晒月光

image

image

黄埔古港

image

image

古港的珠江边有着广州最地道的文化。

image

独具浪漫情调的沙面,很适合情人在月夜漫步。

晒月光

这个中秋,如果你和家人依然选择不远游,待在广州也有许多精彩的去处。在广州,你不必每年中秋都去人头攒动的白云山、越秀公园,也不必每次都只能在城中几家大酒店中做选择题,广州地方那么大,当然有许多独特的地方也很适合与家人城内私密地团聚,让你度过一个私密的中秋之夜。

文、图片整理/记者陈薇薇

信义会馆

江边晒月光

亮点:在旧工厂改造的江边时尚地晒月光

私密度:【【【【

北京有798,上海有八号桥,广州有信义会馆。信义会馆,如今已经成为远近闻名的广州标志性时尚地。这是一块紧临广州最美珠江边的宁静角落,虽然名气越来越大,但真要到信义会馆,却要从芳村大道一条不起眼的巷子进入。中秋之夜在这里赏月,既私密又最贴近广州的时尚脉搏。

信义会馆是由一片旧厂房改造而成的,里面的大部分建筑保留了工厂古朴的外貌,恰好与中秋之夜的传统韵味相贴合。在信义会馆,有百年的老榕树,有现代的雕塑作品,有回归自然的木栈道,还有岭南特色的园林绿化,这块珠江边上的休闲宝地,将历史韵味和现代情调融合在一起。中秋之夜,推荐到江边的信义灰调晴天用餐,这也是利用上世纪50年代旧厂房改造的餐厅酒吧,这个外墙灰黄的餐厅仍保留了过去厂房的旧貌,屋顶很高。餐厅酒吧门前有一大片露天的座位,在这里用餐,吹着徐徐江风,月光与灯光穿过榕树细密的叶子洒在身上,有种说不出的温馨。你也可以在市内用餐,然后和家人到这里散步,欣赏珠江月夜风情、晒月光。

小提示:信义会馆环境清幽,比较适合一家人静心聊天赏月。如果喜欢热闹,年轻人也可以转战附近的白鹅潭酒吧一条街。

长洲岛

古村落寻广味

亮点:广州最后的古朴村落怀旧一看

私密度:【【【【

这个中秋第一次放假,不妨安排一个全家人“广州一日游”,当然游的内容不能太“大路货”,想特别一点,怀旧一点,就到广州的长洲村去探访广州的古村落。长洲岛位于广州东边,是黄埔区珠江上的一个江心岛,如今到长洲岛已经十分方便了。从广州市区开车到长洲并不太远,可以早晨一家人喝完早茶,再一起前往长洲寻幽访古。进入这片幽深的古村中,城市的喧嚣立刻抛在身后,漫步千年历史的深井古村落,脚踩着青石板,对于喜欢研究古建筑的老人家来说,这里是怀念老广州的好地方。中午,在长洲有名的金星农庄体验农家乐,老人家可以亲自在菜园浇水摘菜,年轻人可以玩空中飞人、水中滚筒,小孩子还可以在这里荡秋千,到处充满了浓郁的乡土气息。

另外,你还可以到黄埔古港的艇仔餐厅上吃一碗正宗的“艇仔粥”,共同追忆脑海深处的儿时片段。在离广州琶洲会展中心不远的黄埔古港,是古时辉煌的港口古村,古港所在的黄埔村,如今已经呈现出许多新颖的面貌了。不过,对于老广州来说,最不能错过的就是村子里的两家老字号粥店了,一家是鸡记,另一家是猫记,每次去都挤满了人。古港中最生动的就是小街市了,每天白天沿路边都有许多摆卖的小贩,售卖蔬菜、当季水果和鱼虾干货,许多老广州大老远地开车或者搭公车前来购买,图的就是新鲜。

小提示:从天河黄埔大道往东走到鱼珠码头,可搭乘去黄埔军校的船,每小时一班,逢15分钟开船。如果开车,也可以车渡,车满即走。

古港的粥店一般白天营业,到傍晚就纷纷收摊了,如果想就近吃顿中秋团圆饭,可以到附近的仑头吃海鲜。

沙面

月夜下牵手漫步

亮点:在风景最美的星巴克叹夜色

私密度:【【【

不少广州人喜欢在中秋之夜到珠江边散心赏月,沙面是其中一个好去处。在清雅的月色下,徜徉于古老的街道古巷,看昏黄的路灯照耀在有历史的老建筑上,散步到江边欣赏江面上的宁静月色,这种感觉的确非同一般。这里向大家推荐到沙面星巴克附近赏月,可能会有人觉得诧异。老实说,星巴克的确不是个适合合家团圆的地方,不过沙面的这个星巴克,由于选址特别,很值得一去。

其实,情侣们可以在各自陪完家人吃团圆饭之后,再和心爱的人到这里来叹夜色,享受二人世界。沙面的这个星巴克虽然地方不算太大,但是给人很舒服的感觉,由于开在沙面老建筑中,因此,这也是一家有长廊的星巴克,颇有岭南风情。随便点一杯卡布其诺,或者一块咖啡月饼,在露天的咖啡座下肩并肩窃窃私语,温暖的甜蜜感觉就会从心底油然而生。品完咖啡月饼已是深夜,手拉手静静地走在沙面的曲折小路上,这才是最美最原味的沙面中秋夜。

小提示:虽说是室外咖啡馆,但沙面的星巴克为了保护环境,会劝说客人不要在星巴克范围内吸烟,大家也要注意遵守这一规则。

2008-09-02 来源: 广州日报 作者: 陈薇薇

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