#
大学未卒,身先入此行。时光飞梭,顿悟跌打滚爬,五年已逾。
回首往事,历历在目,酸甜苦辣,肚中自知。。。
而如今,身在东瀛,蹴鞠行事,偶遇同行,故作此文,为之共勉。。。。。。。
================================================本文说明===================================================
当别人问起我软件行业和其他行业的最大区别时,第一个让我想到的不同点便是理性的思维方式。软件行业人的大脑会在经过几年的和各种语言打交道之后,也逐渐学会用继承,多态,抽象,扩展等方法看待各种问题。故此,当自己对待在日软件开发工程师有些许的话要说的时候,一定会选择一个结构完整,有着许多共通部分的父类来继承,然后针对在日软件开发工程师独有的特性,进行子类的扩展,不过整体结构仍然保持父类的特性。上述说明,实在是非此行业不能理解。所以,正如老罗述,彪悍的人生无需解释,只有两种情况需要解释:①自己的亲人,因为不解释会让她们会伤心。②法院
以上!
===========================================================================================================
恭喜,你选择做一个赴日本工作的软件工程师。
悲哀,你选择做一个赴日本工作的软件工程师。
本文面向的读者群,仅指如今身在日本并且从事着软件开发工作的中国工程师。
谨以此文与小春上来日本从事软件行业的兄弟们共勉,同时写给我爱和爱我的人
当我们大一时怀着青涩的记忆进入大学校园,并且选择计算机、通信、电子、自动化、机电等专业时,我想你可能和我一样说不清毕业后到底想从事什么行业。可是,四年就这么一晃就过了,和很多人一样经过熙熙攘攘的招聘会之后,终于找到了一份薪水不错,很多人都羡慕的工作--—传说中的软件工程师。
可是问题在于我们都并不满足于此!为了将来的发展,各自通过各种方式包括外派中介,学校招毕办,各种熟人选择了赴日从事软件开发,真是自作孽不可活。不过,欢迎你和我一样加入这个被其它人认为是风光无限的“赴日软件工程师”吧。
赴日软件工程师とは?(※1ご参照下さい)
相
对国内一些刚毕业的同学或者仍然在国内的同行们而言优厚的薪水(※2ご参照下さい),以及在日本新鲜的生活,发达国家的便利生活不仅仅让你感到生活的充实,更满足了你那不让外人知的虚荣心。Z在日本的几年中,你经常会回头关心一下自己在国内亲爱的同学和同行们的工资和生活,在内心怜悯他们的同时,我们也会为了在日本所付出孤独,寂寞,没尽头的加班的感到平衡。“吃得苦中苦,方为人上人”这句话在日本的几年中你说的最多,不管对自己、朋友、还是爱人。对了,在日本的几年中,你会觉得自己除了吃饭开销、住房、小春足球活动、一个月几次的飲み会之外,存款已经开始一天一天多了起来。心里已经打起了小算盘,开始考虑以后买套1000万的小房子,开始谈恋爱,开始考驾照,开始看车子。总之,你对前途充满了信心,你确信认为这种“贫嘴张大民”式的日式小资生活会永远的持续下去,即使不是变得更好的话。
可是在日本的日子就这么一天一天的过去了,忽然有一天你突然发现你自己快30岁了,甚至已经超过 30岁了,渐渐你心里已经开始有了一种说不清楚的不安的情绪,因为你发现日本所能给你的生活并不象想象中一样变得越来越好。你也突然发现国内以前瞧不起的亲爱的同学和同行们已经不少买了房子,车子,结了婚,有的甚至还养了孩子,你才开始明白自己虽然每个月赚的比他们多,可是存下来的钱比起他们最多是中等偏上。工作中更加有让人感到不舒服的地方,来了几年了还是每天用相同的语言开发着各种项目,每天真正用日语交流的还是不超过100句甚至还必须加上手语才能解释清楚。每天还是必须做在电脑前用C++,Basic,COBOL,Pro C*等工具写上500行以上的代码附带测试,自己虽然是前辈了,不过手下还是没有一个小兵,对工作的不满只有在飲み会的时候才敢偶尔发发牢骚。
你终于开始迷茫“老子再过几年后,到底要干什么?”,这句话常常出现在你的心里。 “敢问路在何方?路在脚下。。。”,不过西游记里面猴兄和八戒兄这么认为是可以的,你呢?
那就让我们抱着研讨的态度,来看一下我们大家的出路吧:
第一条:继续留在日本做你的软件开发工程师吧。
如果大家真的留心数过的话,发现还真的有很多朋友在30岁以后还在从事Coding工作,我这里说的从事,是指你还需要天天在破旧的电脑边上用 Visual Studio.Net或者JBuilder等开发工具甚至于UltraEdit在表达你的逻辑思维。与你手下带着几个小兵无关,与你写不写仕様書无关,也与你是否被叫做SE、BSE、主任研、主幹研的帽子无关,只要你还需要亲自写代码,你就属于这一类。仔细的分析一下这类人,还真发现他们有以下的这些共同点:
1. 痴迷工作或者痴迷电脑,晚上八点到十二点的这段时间,基本上是在电脑桌或工作台前渡过的。
2 。 头发三七开,不会去刻意格好つける。
3 。 近视+戴眼镜。
4 。 体型偏胖或偏廋,不在正常区间。
5 。 不喜欢与人交住,不参加小春足球活动,飲み会,MSN上常联系的MM不超过五个。
6 。除了程序逻辑之外,不太讨论其他的话题。
7 。 无远期未来计划,对五年后自己生活怎么样、从事什么工作说不清楚。
8 。 俭省,甚至扣门,从不乱花钱,每个月甚至可以节省20万日元。
即使你是还不到30岁的软件开发工程师,如果你想知道是否会在30岁后还从事软件开发,那么就请把自己和以上几条逐一比对。四条疑似,如果五条一样的话,那么恭喜你,你已经可以看到自己的未来了。
这些朋友们通常抱着过一天是一天的态度生活,到了这个年龄,也不敢再轻易的换工作了,刚来日本时的锐气慢慢的被生活所削平,唯一不变的希望是有一天中到彩票的头奖。说实在话因为他们的性格所限,基本上可以确定他们以后不可能在人际关系复杂的职场上获得更好的发展。当个Sub Leader混个SE,带几个人写Coding已经是他们发展的顶点。至于以后的人生之路,不仅他们自己迷茫,可能老天爷也在头痛。
简单建议:性格决定命运。所以说要改变命运,先改变性格。坚持半年晚上不从事工作、游戏及电视(不过说实话,这个还真的很难)。用此时间与人交往,参加小春足球活动,飲み会,相信你的人生可能会有所改变。
第二条:软件开发担当
如果你现在还没到30岁,而且已经是Sub Leader、制品担当、或者项目经理,或者你眼看就有机会被提升为这类头衔的话,那么我要恭喜你,你走的是从“生产从事”到“开发管理”这条金光大路了。有一点很明确,你不仅拥有很高的软件专业技能,而且很显然,你也有着很强的人际交往和日语沟通能力,你这类人根本不需要对未来有着任何的担心,不要说在日本,即使在沙漠你也很容易白手起家。
你能不能成为这类人也很容易区别,就像下围棋的二十岁不能做国手终身无望一样。你如果在工作三、四年以后,也就是说二十七岁左右就会发现自已工作中和客户交流或者对着手下的小兵指手划脚的时间比亲自Coding的时间要多了,而且开会的时候已经开始学会说:“あのさー、えーどですね....”,那就说明你还是很有希望成为开发管理这类人的。相反,如果你快30岁了还天天埋头于Coding、 Debug,电脑键盘上被按的最多的竟然是F9和F10(内行不用解释,外行解释了也不懂),或者30多岁了你还没升到部门经理(虽然公司总是让你觉得很有希望),基本上可以确定你不是开发管理这类人。好了,如果你确定你是这类人,那么你唯一的想法就是尽快爬上中层和高层,因为有时候工作当中的偶然性太大,虽然说一个萝卜一个坑,可并不是所有的萝卜都有坑的!
简单建议:和公司的某个课长或者部长搞好关系,关键时候,总是需要人顶你一把才能把你这个萝卜顶到那个坑的。
第三条:转行到相关的市场部门
这里所谓的[相关的],也就是所谓的软件公司的市场部门。通常在一个软件公司里面,开发和市场都是最重要的两个部门,也是最容易产生冲突和矛盾的地方。市场部门天天抱怨由于开发做得不好,不仅不能开发新的市场而且一些老客户也转用其他的系统。而开发也天天在抱怨自己开发出这么好的东西,市场部门却卖不掉。从另一方面来说,这两个部门也确实有各自欠缺的地方,市场部门的人总是缺少从技术角度看问题的能力,往往答应了客户要实现这样那样不能实现的功能,随后被公司的技术部门笑话。而技术部门也往往缺少从用户角度看问题的态度,往往不知道一个ボタン放在哪最方便用户,跳出的メッセージ的内容虽然觉得非常当たり前,可是用户更本不知所云。
所以,如果你对软件开发没什么兴趣,不妨和你的上司谈谈试着转到市场部门。如果可以成功转行的话,相信你以后在市场部门的发展应该是非常好的。因为在和人打交道方面,你要学到和他们一样,可能只需要1年左右。而在技术方面,他们永远追不上你!
简单建议:流利的日语这是基本,除此之外,还需要做市场的样子。比如要学会天天穿スーツ,学会格好つける,学会用一些男用化妆品打扮自己,比如ブルガリ的男士香水。
第四条:自己接项目,开公司
关于这条,有两点需要强调的。第一是在这里所谓的开公司指的是在国内开一家自己的公司。第二是这个顺序是接项目然后开公司,而不是相反。
如果你是从国内有过对日软件开发经验的软件工程师的话,我想你应该会知道和了解国内的一些对日软件的开发模式。往往一个在日本有着很多年软件开发经验的部长,从一个大公司例如接了一个项目带到国内,然后和人合资创立了一家公司,找了一批刚刚毕业,没什么经验的大学生从事着周而复始的劳动。为什么说是劳动呢?如今的软件开发其实早就没有当年的神秘感,而且对日的软件开发更是如此。国内理工科大学毕业生,即使是刚刚毕业的学生,只要学过一点C++, JAVA,Cobol的话完全可以在短时间内胜任PG的工作。从日本客户这边得到的是每个人月20-30万日元的开发费用,而在国内付出的只是每个月 3000-4000的人月成本,这样一来,中间的差价就可以让这位老兄笑的合不拢嘴。这样的公司往往有以下特点:
1. 声称自己是日企,其实管理上全部中国人,只不过做的是日本软件的外包。
2. 员工的福利很差,四金总是用劳动法规定的最低标准来缴纳。
3. 总是对员工说干得好的话,有被派到日本的工作机会。日本的出差,对员工来说是奖励。
4. 开发语言通常为Cobol,Pro* C,Java J2EE等。
5. 开发的项目通常为金融,证券等ERP系统。
6. 无偿的加班,员工怨音载道。
如果你在上述这样的公司有过工作经验的话,我想你一定会抱怨公司的待遇以及老板的剥削。可是你有没有转换过一种角度来考虑问题呢?难道我们不能成为这样的人,反过来剥削别人吗?答案是肯定的,别人可以做到,我们也可以做到!
简单建议:扩大你的人际交往圈,多认识一些在日本做软件的朋友。说不定在什么时候,大家可以有机会进行项目合作。
第五条:第二职业与兼职
这条与其说是出路,不如说是一种暂时的赚钱方式。当然它的前提是你还不至于太忙,至少还有自己的一些闲暇时间。这种方式觉得最适合那种现在收入已经比较高,或者对自己现在的工作比较满意,不过又想赚点外快的那些人了。
对于在国内搞了好几年的软件工程师来说,一个人做个公司网站,内部管理系统啥的其实并不是什么很困难的事情。国内的技术论坛上面,下载几个网站的模板,然后改一下公司名称,图片,风格然后卖个1-2万的事情大家也不是没做过。内部管理系统也是一样,对于一般的小公司来说,所谓的管理系统也不过是实现增,删,改,查的需求而已,当需要稍微复杂一点程序的时候便到网上去找个控件+注册码便可以简单实现。既然在国内可以这样,为什么在日本的各位软件工程师没有想过呢?而且想对国内想对便宜的价格来说,同样的系统在日本的价格应该更加合理。这样下来,每个月增加个10万左右的收入也不是什么很难实现的目标了。其实,最重要的不光是钱的问题,积累的人脉关系也将成为你以后无形资产,为你以后在国内的发展做一下铺垫。
简单建议:多认识一些不同行业的日本人。不光是做IT的,其他比如服装的,机械的。总之尽快融入日本这个社会,和方方面面的人多打交道。钱赚多了,别忘记给自己爸妈和女朋友买点东西,毕竟自己在国外工作,平时照顾不到的地方用其他的方式来弥补一下吧。
从2004
年11月20日参加了汇丰(香港上海汇丰银行在广州的软件开发中心)在广工的宣讲会,到11月30日投了申请表,到12月8日的笔试,再到12月30日的
面试,2005年1月26日去体检。。。。。。终于尘埃落定,一直觉得自己是挺幸运的一位,刚好遇到汇丰今年大招员,第一次的工作面试就找到一份不错工
作。把这段幸运的经历记下来,和大家分享一下,希望可以对还在找工作的同学们有些启发,作一个参考!
简历:一般大型的公司是不去招聘会
的,都以校园宣讲会的形式去招揽人才,而且宣讲会一般都开在一些重点大学,所以要多出去走动,去别的学校参加这些活动,搜集些资料!汇丰并不收别人制作的
简历,而是得去上网下载些APPLICATION
FORM来填,填了四页的英文表格,这是必须迈出的第一步,千万不要一看到是英文表格就吓倒,一边查字典填出来也是可以的,不管怎么说投了就有一个希望,
而不投是无论如何都没有机会的!
笔试:大公司的笔试都不会是些很专业的试题,因为它们注重自己去做人力资源的开发,所以它关注的是你的潜力(如学习,交流沟通,团队,处理压力等)。
整个笔试历时三个钟,第一部分是数列规律,有些类似于考公务员的那种数字推理题,15分钟做30道题。
第二部分是与应聘职位有关的专业知识的阅读,12篇阅读,每篇50-100个单词,共48道题(判断对错或不确定),25分钟完成。
第三部分是逻辑推理题,是些XYZABC通过一些黑盒然后掉换了顺序,交叉成一个网状图,然后推理黑盒代表什么,按照推理出的黑盒的意义再去做些题。35分钟完成40道题!
笔试考的就是人的逻辑思维能力,在面对压力下的稳定性等,像第二部分阅读都是很短的几句话,很多可以直接看出答案,但就是每一篇的字体不同,字的大小也变
来变去,有一篇甚至是没有空格符号的一大串字母直接过去。时间肯定是不够全部完成的,但不要紧张能做多少就算多少。我第一部分完成24道,第二部分26
道,第三部分28道!
面试:
面试官是两个从香港过来的女士,主面试官是Grace Ma(以下简称G),另一位是Miss Li(以下简称L,还有我(以下简称ME)
G:首先好多谢你来参加我地汇丰既面试,你平时讲英文多唔多架?
ME:ER.........(她们听到我的ER后笑了一下),一般啦!
G:甘不如我地用英文倾下先,之后再转返用广东话啦
ME:好啊!
G:First of all,please introduce you educational background!
ME:I will be graduated in Guangdong University of Technology next year!My major is automation!
G:OK.....
L:Is automation relevant to IT?
ME:Yes,we learn how to design a system and make it run automatically,so we have to design the hardware and also the software.
G:OK.Do you have any experience of IT project?
ME:Yes,it's a small game.(大一的时候学C语言,做过一个贪食蛇的游戏)
G:A game?
ME:Yes,a small game which you can commonly find in some mobile phone!
G:OK,a small mobile phone game!When did you finish this project?
ME:When I was a freshman.
G:You meant the first year in the university?
ME:Yes.
G:Do you have any project finished recently?
ME:Yes,a website.
G:Why did you do this project?
ME:Because I joined a club and it needed a website.
G:What's it about?
ME:It's just an introduction of the club.
G:Did you have any difficulty in this project?
ME:Yes,since
my major is automation,not relevant to design,and I knew less about
HTML,ASP.So I had to learn how to design some pictures,arranged
them,made the page look more beautiful and also I had to learn how to
use some software,such as Photoshop,Dreamwaver,Frontpage,Flash.
G:How much time did you spend in completing this project?
ME:About one month.
G:Was there any deadline for this project?
ME:No.
G:OK.Why do you want to be an S.A.P(system analysist/programmer)?
ME:I think it's a challenge.
G:How can you find challenge from it?
ME:
Because.......(开始紧张,因为没准备这问题)....others give me the task......and I
have to finish it on
time......(紧张,胡言乱语)....and.........(大概停了五秒)......sorry....I like to put
somebody under control.Some of my friends like to play PC game,and they
may say they are the king of the game when they win a battle or win the
game.But I say:"You are not the king,the king is the designer of the
game.You just deduce the result the designer designed,you are under
their control."......I like to be a programmer.Consider the customer's
demand,design the software make them like my design and also under my
control.I like that sence of
accomplishment.(这段话是平时对于一些沉迷游戏的人的看法,写过在文章里,再添油加醋,总算派上用场了)
G:(或许她看出我的紧张,就转回用广东话了)你有无做过兼职啊?
ME:无
G:点解呢?好似宜家好多同学都有做兼职哦!
ME;因为我大一大二既时候有系度做学生会同社团既工作,到左大三后专业课程比较紧,所以无时间做.
G:甘你下学期有无打算做下兼职呢?
ME:无(我只是老实说,不知道她为何好像无奈地一笑)
L:点解唔做呢?下学期仲有课咩?
ME:下学期仲有毕业设计,毕业论文要做.
G:甘你无打算过毕业设计做咩啊?
ME:我地可以做D例如电梯控制,图像识别,办公自动化系统.
L:题目系老师定既,抑或系自己选啊?
ME:老师会俾D意见,都可以自己选后申请.不过仲未定住,因为仲要睇下可以申请到边间实验室做,因为要配合实验室D条件!
L:甘用咩做?
ME:如果系电梯控制最常用PLC啦,图像识别用C语言,办公自动化系统可以用VC啦
L:甘你擅长用咩语言编程啊?
ME:C语言啊,汇编
G:你之前讲话你做过学生会啦,甘你可唔可以讲一D你参与过既活动,等我地睇下你既能力啊?
ME:
可以!我大一果阵时通过面试,加入左学生会既宣传部.其实我当初加入可以话咩都唔识,画画系平时有睇下漫画书,但都唔系几识画,书法细个学过,好多年无写
过啦.不过我比较积极,每次有活动我都会去参加,仲报左书法选修,无事就拿些漫画来照住练画.期间我参加过校运会,露露赠饮,漫画比赛等活动既宣传,仲系
师兄既带领下去联系漫画比赛既赞助商。终于由于我既积极勤奋,仲有人际关系处理得好,所以有幸系大二被提升为部长。
G:甘点解你当初咩都唔识仲要去报宣传部呢?
ME:
因为我觉得.......可以学到野咯,当初我睇到学生会招生果份FORM,觉得宣传部可以...学到画画啊,练下书法
啊................ER.....我觉得工作就要照住自己特长来找,在学校主要是学东西,所以就要照着自己唔识既,薄弱既环节去学咯!好
似我有一次练紧书法,有D同学行过就会话,练咩鬼啊,不如出去玩好过啦!我就笑住话:"练多一样,就多一样生存技能啊嘛,宜家就业压力甘大,到时毕业稳唔
到工,都可以去摆个档口帮人地写挥春!
G:(笑.....)甘你做左部长之后有做过咩工作啊?
ME:其实第一年做干
事既时候,我就发现宣传部既工作好被动,而且有好多唔系几好既方面,有阵时就好似一台打印机甘,人地过来按一下,我地就打几张海报出来,工作比较单调,所
以我做左部长之后想有所改变咯!所以我上任第一件事就系同其他部门沟通好,要出海报要先支会我地,我地可以尽早安排好工作.做好自己既本职工作之后,就试
住带D新生去组织一D活动,等距地有多方面既锻炼!先后做过新生既招干工作,做面试官面试人地啦,做迎新晚会啦,校运会啦,仲有一次宣传部自己既活动,同
校外既一个义工社团做一个义卖,募捐的活动,不过呢个活动最后由于学校审批方面唔批,所以就搞唔到,但系都带住D新生做左好多前期既工作,锻炼到好多野.
G:你头先话你做面试官啦,甘你面试人地既标准系咩啊?
ME:我地会系现场有D纸笔,俾距地SHOW下画画书法既技能啊.但系呢个并唔系最重要既,因为系画画写书法既过程中可以睇到好多野,例如细唔细心啊,有无责任心之类既野.我觉得责任心好重要,因为我一交份工作俾你,你如果无责任心,唔按时完成,甘成个活动就会俾拉低晒!
G:(点头)甘你做部长后有无咩困难啊?
ME:
Mm.....最大既困难就系成个团队气氛既带动问题咯!因为距地大部分都系新生,大家互相之间并唔熟悉,所以我就每两个星期举行一次例会啦,除左工作之
外,大家互相之间都可以倾下计啊.仲有安排工作时,每次都会分唔同既组,例如呢次A同B一组,下次就A同C一组,等距地系活动中去互相熟悉.
G:(睇下Miss Li问仲有无问题,回复无,就对我讲)甘你有咩问题想问我地呢?
ME:我从你地既网站上边睇到啦,从S.A.P开始,经过两年,系有机会升做IT OFFICER,跟住一级一级甘升上去啦,我想请问下你地多久评估一次绩效,评估既标准系咩
G:我地新招D人经过24个月既培训同工作之后呢,如果表现良好,就有机会升做IT OFFICER架啦(她的回答很模糊,我从汇丰的网上也可以找到,我也没再追问下去,反正我的目的就是想她觉得我对工作很有兴趣,有上进心,就够了)
ME:OK.我想请问下S.A.P具体系做D咩呢?
G:甘你来呢度应聘,你唔知呢个职位做咩噶咩?
ME:知啊,系统分析员主要系做D分析既工作,程序员主要系做coding咯!但系一个软件工程入边有好多part,我想知道具体做边一part.
L:广州呢边呢分析既工作好少既,最主要都系跟翻香港果边既file,做coding既工作,主要系做一D银行系统既开发测试咯
ME:(点头)OK
G:甘你仲有无问题啊?(无)甘OK,多谢你今日来参加我地汇丰呢个面试,如果有进一步既消息,我地会系12月中旬通知你!
ME:好既,唔该晒.
(就这样走出了他们的OFFICE,当崩紧的神经放开的时候,头脑一片空白,感觉好累......面试过程中我是关了手机的,也没看手表,估计应该是三十几分钟吧)
总结:
感觉自己真是一个幸运者,第一次的工作面试,而且遇到汇丰今年大招员,就让我中了这么份不错的工作.
在我刚投汇丰的时候,老实说是没有信心的,但我后来还是迈出了第一步,因为我对自己说有希望我就要去尝试,当去见识一下知名企业的面试也好.我也不怕糗,因为我觉得没有什么事比我读了这么多年书都找不到工作再糗的事了.
第一次的工作面试,感觉一般,特别英文对话的时候,由于说不流利而带来的紧张,感觉那时候特糗,但不管怎么说我都做出了一个尝试,一个尝试就是一个希望,如果我连试都没有,就连一点希望也没有,我相信我现在也在懊悔不已.
面试前做了不少准备工作,包括请教过一些已经去过面试的人,上网查找一些面试必问的问题还有回答等,后来发现真的受用无穷,幸运总是会光顾有准备的人嘛!
啊啊啊啊啊啊 | 2006-04-05 21:05 |
唉~~~ |
|
janly | 2006-04-05 21:58 |
网上这么多这种贴,汇丰的HR会不会看到啊,那以后我们不是更难.......... |
|
天空之城 | 2006-04-06 21:00 |
看到也不会怎样。。。。。。。。。
汇丰一直都是问这种类似的问题的。。。
大公司不会在乎你知道或者不知道的。。。。
其实外企问的问题非常简单,因为大部分外企的问题都非常类似,但是关键是你答的技巧,
人云亦云的东西太多了,关键是要表现出你自己就好了。 |
|
竹风 | 2006-04-07 11:46 |
嗯,同意楼上的. 50年不变的问题 |
|
sonic | 2006-04-09 19:35 |
其实问的问题本身不重要,而答问题时的逻辑组织和方法技巧才重要。一个好的HR问你几个问题就大概知道你是怎样一个人了。 |
|
happyjinting | 2006-04-17 15:19 |
天空之城 有恋童倾向~~ |
|
水d | 2006-04-17 18:31 |
汇丰的HR好劲的,面我的是jackson yu , 面完后还很“好人”,马上给我总结,看出我的弱项在哪里,还问我是不是,呵呵~~我回答:相对来说~是~ |
健康九法
大脑为精明之府 日梳五百把病除 头为精明之府,人体之重要12经脉和40多处大小穴位,以及十多个特殊刺激区均会聚于头部。用木梳或骨梳替代小银针,对这些穴位和经脉进行所谓针灸性按摩或刺激,将去病健身。勤梳头的确是一项积极保养人体精、气、神的最简单易行、最经济的长寿保健对策。
脚底为第二心脏 常搓涌泉益健康
中医学认为脚上的60多个穴位与五脏六腑的12条经脉着密切的联系,布满了相关全身各器官的反射区。但由于脚底部离心脏甚远,抵抗力低下,是人体的先天薄弱环节,客观上为寒湿邪气病毒的侵袭提供了有利条件,所以说脚部的保健比其他部位显得尤为重要。经常温浴后搓涌泉穴,可去病延年。
日咽唾液三百口 保你活到九十九 中医认为,唾液是人体的精华,贮于丹田,再化津还丹,遂成精气,起到和脾健胃,濡润孔窍,润泽四肢五脏,强肾补元,滑利关节,补益脑髓的作用。所以日咽唾液三百口,保你活到九十九,是很有道理的。
日撮谷道一百遍 治病疗疾又延年 谷道,又称肛门。撮即上提收缩也。通俗地讲,就是做收缩肛门的小动作。孙思邈在《枕中方》中规劝世人“谷道宜常撮”,认为肛门周围的肌肉要间歇处于运动状态,才能养生健体,尤其对防治痔疮有特别疗效。
朝暮叩齿三百六 七老八十牙不落
叩齿,就是指用上下牙有节奏地反复相互叩击的一种自我保健养生法,俗称叩天钟。中医学认为经常叩齿,不仅能强肾固精,平衡阴阳,疏通局部气血运行和局部经络畅通,延缓衰老。
随手揉腹一百遍 通和气血裨神元
揉腹,即用手来回按摩腹部,包括腹壁、腹腔以及内脏的一种养生保健法。中医认为,腹为人体五脏六腑之宫城,阴阳气血之发源。勤揉腹,即可以调整脾胃,通和气血,增补神元,敷养肾精,充实五脏,驱外感之诸邪,清内伤之百症。
人之肾气通于耳 扯拉搓揉健身体 中医认为,耳为肾惟一之上外窍,双耳灵健则肾经通,肾气充足,肾精盈满,则听觉灵敏。扯拉、按摩、搓揉、点捏耳朵,实际上就是对双耳进行各种形式的物理刺激和针灸治疗。
消疲健美伸懒腰 血运畅通最为高 所谓伸懒腰,就是指伸直颈部、举抬双臂、呼吸扩胸、伸展腰部、活动关节、松散脊柱的自我锻炼。
安心郊游延年寿 调身调息加调神 医学研究表明,情绪与健康二者紧密相连。凡情绪乐观开朗之人,可使其内脏功能健康运转,增强对外来病邪的抵抗,同时在平静的情绪状态下,方可从事持续的智力活动。因此,古人的摄生之道之一,便是安心养神。儒、释、道三教皆有养生之法,并皆主张郊游。
----步骤 1. 用计算机管理员账户进入本机wingdows操作系统,启动WAS服务器后,从 WebSphere 管理控制台,展开安全性 -> 用户注册表。单击本地OS(本地操作系统),并输入 WebSphere 管理员标识。
a. 在服务器用户标识字段输入管理员用户标识。
b. 在服务器用户密码字段输入与标识关联的密码。
单击确定。
----步骤 2. 转到全局安全性窗口,单击启用安全性。请验证实施 Java 2 安全性已关闭。其它选项默认。
----步骤 3. 单击确定-> 保存。
----步骤 4. 重新启动 WAS 服务器以使更改生效。
雖然Reqular
Expressions(以下簡稱REs)在這個論壇或是其他網站都可以找到相當多的資料,但是當我自己要學的時候才發現有很多小地方還是看不懂,所以才
以java API裡面的說明為主,把每個符號的解釋一一弄懂,終於對REs有了初步的認識。
所以這份文件是以java
API提到的符號解釋,加上我自己的心得及範例所整理出來的,我用"字元"和"字元組成",這兩大部分來解釋REs的符號,大部分的解釋都有範例,這樣比
較容易瞭解,沒有範例的部分不是太簡單,就是我找不到例子,不過對於認識REs應該沒有多大影響。
因為我算是REs的初學者,所以難免有觀念上的錯誤,加上很多"冷門"的符號,要找到正確的解釋都很困難,因此我沒把握所有的資料都是正確的,如果各位有發現錯誤,還請加以指正。
首先是字元,REs的基本元素就是字元,所以對於字元有相當細膩的描述方式,而且很多時候描述方式都不是唯一的,所以不必拘泥於找到最完美的寫法。
字元分兩部分來解釋。
1.一般字元,在還沒做字元組合時,下面這些都只是"一個"字元,先要有這個觀念,才不容易弄不清楚字串和字元的區別。
x : 一個字元,例如 "a" 表示要找含有這個字元的部分。
[abc] : 這個字元可能是a或b或c
[^abc] : 這個字元是除了"a" "b" "c"以外的。
[a-zA-Z] : 這個字元是a到z或是A到Z。
[a-d[m-p]] : 這個字元是a到d或是m到p (聯集)。
[a-z&&[def]] : 這個字元是"d", "e", or "f" (交集)。
[a-z&&[^bc]] : 這個字元是a-z但b c 除外,等價於 [ad-z] (差集)。
[a-z&&[^m-p]] : 這個字元是a-z但 m-p 除外,等價於 [a-lq-z] (差集)。
除了放在一開始的"^"以及兩個"&&"以外,放在[]裡面的都當一般字元。
可是\比較特殊,要\\才能當一個\,所以程式裡面必須寫\\\\,例如,想查"\"用[]包起來要寫成"[\\]",可是java在字串裡面要寫String pattern="[\\\\]"。
2.特殊字元. : 所有的字元,不一定包含換行。java REs的"."預設是不包含"\r"和"\n"的,但是可以用(?s)來讓"."等於所有字元,(?s)的用法下面還有說明。
\r : Carriage return。
\t : TAB。
\n : 換行。
\f : 換頁。
\e : escape。
\d : 數字0-9。
\D : 非數字,數字的除外集合。
\s : 會產生空白的字元也就是 [ \t\n\x0B\f\r],也就是 " "(空白)、"\t"、"\n"、"\x0B"、"\f"、"\r"。
\S : 非會產生空白的字元,上面的除外集合。
\w : 文字 a-z A-Z _ 0-9,所有的英文大小寫,數字和底線。
\W : 非文字,文字的除外集合。
\ : 把之後的特殊字元當作是一般是字元,例如"\\"等於一個"\","\["等於"["。
\Q \E:\Q到\E符號之間的特殊符號都當一般字元處理,例如"\Q(?:X)\E",符合的字串是"(?:X)"
^ : 行首,例如"^e"會找出所有在行首的"e",在[]裡面如果是第一個代表反相,如果不是第一個也當一般字元。
$ : 行尾,例如"e$"會找出所有在結尾的"e"。
\b : 符合文字邊界(word boundary)。也就是說在字與空格之間的位置 例如,'re\b' 符合"are" 裡的're'但是不符合"area"裡的're'
\B : 符合非文字邊界 例如,'re\B' 符合"area"裡的're'但是不符合"are" 裡的're'
\A : 輸入的開始。
\G : 前一個符合的結尾的地方。
\Z : 輸入的結尾去掉結尾符號的部分。例如字串"ABC\n",pattern "ABC\Z"就可以取得"ABC"。
\z : 輸入的結尾。例如字串"ABC\n",pattern "ABC\z"就不相符。
所謂的輸入,是指一次的處理資料,例如String s="ABC\nABC\tABC",就算一個輸入(input sequence)。
到這裡為止是對字元的描述,字元的所有的可能情況應該都可以涵蓋了,可是光是字元是沒辦法構成字串,所以接下來是把字元組成字串的方法。
字元組成,字元組成分三部分來解釋,下面符號的X和Y可以是一個字元也可以是一個Group。
1.簡單組合,就是把字元排在一起。
XY : 單純排列在一起,例如"ab"就是找"ab"這個字串,和"[ab]"不一樣,"[ab]"是代表"一個字元"可能是a或b。
X|Y : X or Y,例如 a|b,而以字元而言a|b就等於[ab],所以對單一字元效果不大,主要是用於字元範圍的[]|[]或者群組()|()比較有意義。
例如[a-z]|[0-9]表示不是小寫就是數字,(abc)|(123)表示是"abc"或是"123"。
實例 "c|Car"(等同於"[cC]ar")相符字串是"car"或"Car"。<-錯了,下面有被糾正的說明,所以就不改這裡。
另外abc|def是指"abc"或"def",而不是"ab[cd]ef"。
(X) : 群組,將多個字元包裝成一個群組,和單純排列不同的地方是,群組可以參照,也可以對群組設定出現次數,
例如(abc)+是指"abc"出現一次以上,abc+是指ab和一次以上的c。
群組參照舉例來說比較容易懂,例如"(.)(.)(.).?\3\2\1",可以找出3個字的回文。如"abccba"、"xcdfdcx"。
群組還有一個值得注意的是,群組0是留給整體的比對的結果,例如上面的例子group 0是"abccba",group 1是"a"、group 2是"b"、group 3是"c"。
有了群組參照的觀念,後面的non-capturing group就會比較容易瞭解。。
Group的另一個對應符號是
\m : m是數字,表示參照前面的group,如上述的範例。
2.重複次數
出現次數接在字元之後,表示這個字元出現的次數,接在Group之後就表示group的出現次數。
次數描述有三種quantifiers,
Greedy quantifiers
X?: X出現0或一次
X+: X出現一次以上
X*: X出現0或一次以上
X{n,}: X出現至少n次
X{n,m}: X出現n到m次
X{n}: X出現n次
Reluctant quantifiers
X??: X出現0或一次
X+?: X出現一次以上
X*?: X出現0或一次以上
X{n,}?: X出現至少n次
X{n,m}?: X出現n到m次
X{n}?: X出現n次
Possessive quantifiers
X?+: X出現0或一次
X++: X出現一次以上
X*+: X出現0或一次以上
X{n,}+: X出現至少n次
X{n,m}+: X出現n到m次
X{n}+: X出現n次
光看這樣的說明是無法分出三者不同,以下舉例說明。
Greedy quantifiers
字串 "xfooxxxxxxfoo"
pattern ".*foo"
結果 xfooxxxxxxfoo
Greedy字面翻譯是貪婪,也就是盡可能的取字串,其實最貪婪的是第三種方法,因為Greedy還會把之後相符的資料留下來,Possessive吃的連骨頭都不剩。
Reluctant quantifiers
字串 "xfooxxxxxxfoo"
pattern ".*?foo"
結果 xfoo 和 xxxxxxfoo
Reluctant字面翻譯是勉強,也就是抓最小可能,像這個例子,第一次抓一個x之後發現後面和foo相符,就得第一個結果,然後一直到最後又得到第二個結果。
Possessive quantifiers
字串 "xfooxxxxxxfoo"
pattern ".*+foo"
結果 沒有相符合資料,因為所有的資料都與"."比較相符,最後沒有剩下的字串可以和foo做比較,所以沒有符合資料。
3.Special constructs (non-capturing)
所謂的non-capturing就是說這個group會被比對,但是不會暫存在group裡面,就是最後得到的Group裡面不會有這組資料。
(?:X) :X會取得,但不會被保留,當之後有用\m的時候,這個Group會不算在內,這樣的處理效能會比較好。
(?i d m s u x) : 特別設定的flag設為on。
(?-i -d -m -s -u -x) : 特別設定的flag設為off。
i d m s u x的說明如下:
i CASE_INSENSITIVE : 就是不分大小寫。(?i)
例如
字串 "ABC"
pattern 用"abc"會找不到,用"(?i)abc"就會找到"ABC"。
d UNIX_LINES : \n當作換行,當文件是UNIX的換行格式時,要處理換行就可以打開這個模式。(?d)
m MULTILINE :多行模式下,^和$是以指每一行,不然是用整個字串的頭尾當^和$。(?m)
例如
字串 "ABC\nABC\nABC";
pattern "^ABC$"會找不到, "(?m)^ABC$"才會找到三個"ABC";
s DOTALL : 預設java的.不含\n \r,這個模式可以讓.等於所有字元包含\r \n。(?s)
例如
字串 "htm\nhtm\nhtm"
pattern 用".htm"會找不到,用"(?s).htm"就會找到後面兩個"\nhtm"
u UNICODE_CASE : unicode模式。(?u)
x COMMENTS :可以在pattern裡面使用註解,會忽略pattern裡面的whitespace,以及"#"一直到結尾。(?x)
例如
字串 "ABC"
pattern 用"A B C #找字串ABC" 會找不到,用"(?x)A B C #找字串ABC",就會找到"ABC"。
(?idmsux-idmsux:X) :X是non-capturing group並且設定flags on -off。
X(?=X) : lookahead在要取得的字串右邊,接著X但X不被算在內。例如Jack(?=Sprat) 則只有JackSprat的Jack會被取得,Jack(?=Sprat|Frost),則只有JackSprat和JackFrost的Jack都符合。
X(?!X) : lookahead在要取得的字串右邊,和上面相反,例如Jack(?!Sprat) 則後面是Sprat的Jack不會被取得。
(?<=X)X :
lookbehind在要取得的字串左邊,例如"(?<=foo)bar",找接在foo之後的"bar"。還有裡面的文字必須已知長度,也就是不
能用"(?<=foo+)" "(?<=foo*)" "(?<=foo{1,})",但是可以用"(?<=foo?)"
"(?<=foo{1,2})" "(?<=foo{1})"。
(?<!X)X : lookbehind在要取得的字串左邊,例如"(?<!foo)bar",找不是接在foo之後的"bar"。關於長度和上面符號有相同限制。
(?>X) : X, as an independent, non-capturing group。
因為這幾個符號都是non-capturing的,所以會有一個現象,直接看下面範例會比較容易瞭解
字串 "abc"
pattern "a(?:b)c"
結果 "abc" 但是b沒有變成group 1,這也就是non-capturing。
如果用 "a(b)c" 會得到 group 0是"abc",group 1是b。
字串 "abc"
pattern "a(?=b)c"
結果 抓不到,因為b並沒有被取出,要"a(?=b).c"才抓的到,而且"a(?=b).c"只會與"abc"相符,不會與"acc"等等相符。
字串 "abc"
pattern "a(?<=b)c"
結果 抓不到,因為b並沒有被取出,要"a.(?<=b)c"才抓的到,而且"a(?<=b).c"只會與"abc"相符,不會與"acc"等等相符。
由上面例子可知,這幾個符號都不會把符合的字串取出,也就是會比對但是不會算到結果裡面(non-capturing)。
所以lookahead和lookbehind那四個符號,不適合放在字串中間,另外,因為這幾個符號都是non-capturing,所以在後
面加上大於0的次數都和一次是一樣的,例如字串"XB",pattern"(?<=X){9}B"一樣可以取得B,而pattern""(?
<=A){0}B"也可以取得"B"。
整個java的REs大概就這些了,只是看完這些解釋其實離可以運用還有一小段距離,因為REs需要的是分析pattern的能力,而這種能力要多練習才會。
在自己能寫出pattern之前,可以拿別人寫好的pattern來測試體會一下,下面是一個簡單的測試程式。
這個程式是我小修改網路上找到的範例,會回傳符合的group,方便測試結果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import java.util.regex.Matcher; import java.util.regex.Pattern; publicclass TestRegular { publicstaticvoid main(String[] args) { String inputStr = "ABC\nABC\nABC"; String patternStr = "(?d)ABC"; Pattern pattern = Pattern.compile(patternStr); Matcher matcher = pattern.matcher(inputStr); boolean matchFound = matcher.find(); while(matchFound) { System.out.println(matcher.start() + "-" + matcher.end()); for(int i = 0; i <= matcher.groupCount(); i++) { String groupStr = matcher.group(i); System.out.println(i + ":" + groupStr); } if(matcher.end() + 1 <= inputStr.length()) { matchFound = matcher.find(matcher.end()); }else{ break; } } } } |
測試REs也可以使用一外部工具,例如eclipse的plugin Regex tester,我很多範例跟觀念都是用這個工具去測試的。
最後"反組譯"幾個例子來練習,就是把別人寫好的pattern試著解釋出來。
HTML TAG
</?[a-z][a-z0-9]*[^<>]*>
開始是<,接著有0或1個/,接著是一個英文字,再接著是不限次數的英文或數字,之後是非"<"或">"的字元不限次數個,最後以">"結尾。
相符的是"<html>" "</html>" "<h0>"等。
不相符字串 "<123>"
HTML TAG 之二
<([A-Z][A-Z0-9]*)[^>]*>(.*?)</\1>
開始是<,然後由一個大寫英文字,和不限定個數的數字或大寫字母,構成一個group,接著不限個數的非">"字元,然後是一個
">",不限定個數的字元(用*?才不會一直取到之後的tag去),然後是tag結束的"</",要和第一個Group的值match,最後
以">"結束。
相符的有 "<A HREF="www.google.com.tw">Test</A>"
"<P></P> "<PRE>Test</PRE>"
"<H0></H0>"
不相符字串 "<abc></def>" "<123></123>"
IP
\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
前後都是"\b"表示在獨立的一個字的單元,用"?:"是不算group而已,250-255或200-249或0-199,接著一個".",這樣的group有3次,最後再一次0-255的group。
這樣就是一個0.0.0.0 - 255.255.255.255的IP的pattern,而[0-9][0-9]?也可以改成[0-9]{1,2}。
相符的字串 "140.115.83.240" "255.255.0.0"
不相符字串 "256.1.1.2" "-1.300.1.2"
IP之二
\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
IP之三
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
這是0.0.0.0 - 999.999.999.999的格式
其他例子
"[hc]+at" 相符的有 "hat", "cat", "hhat", "chat", "hcat", "ccchat" etc.
"[hc]?at" 相符的有 "hat", "cat" and "at"
"([cC]at)|([dD]og)" 相符的有 "cat", "Cat", "dog" and "Dog"
"/\*.*\*/" 相符的有 /* Second comment */
以下幾個(都是抄的)適合檢查輸入的值,因為都從^到$,從字串開始到結束。
1、非負整數:”^\d+$”
2、正整數:”^[0-9]*[1-9][0-9]*$”
3、非正整數:”^((-\d+)|(0+))$”
4、負整數:”^-[0-9]*[1-9][0-9]*$”
5、整數:”^-?\d+$”
6、非負浮點數:”^\d+(\.\d+)?$”
7、正浮點數:”^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$”
8、非正浮點數:”^((-\d+\.\d+)?)|(0+(\.0+)?))$”
9、負浮點數:”^(-((正浮點數正則式)))$”
10、英文字符串:”^[A-Za-z]+$”
11、英文大寫串:”^[A-Z]+$”
12、英文小寫串:”^[a-z]+$”
13、英文字符數字串:”^[A-Za-z0-9]+$”
14、英數字加下劃線串:”^\w+$”
15、E-mail地址:”^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$”
16、URL:”^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$”
-------
學習REs最重要是學會找到字串出現的特徵,特徵有時候是出現的位置,例如位置是行首(^),是行尾($),單字開始(\b),單字裡面(\
B),有時候是前後出現的字串,例如要找html
tag的屬性,都會由"<"當開始,到">"結束。而要抓"<a>"的url就可以從"href"開始。但有時候要找的字並沒有
特殊的位置,也沒關係,就把要找的字描述出來也就可以了,例如要抓日期就做一個"(0[1-9]|[12][0-9]|3[01])[-
/.](0[1-9]|1[012])[- /.](19|20)[0-9]{2}"的pattern就可以了。
而其實真正困難的地方在於很多pattern都要看到結果才會瞭解哪裡錯了。
看這個例子
字串 "ABCDC"
pattern "([A-Z]*).\1"
預期要抓到CDC的,結果卻是"A" "B"
"CDC",因為*是0~n所以沒抓也算,而後面的\1如果前面group沒抓到,他也跟著什麼都沒有,最後只有"."抓到第一個結果的"A",同理抓到
第二個結果的"B",然後才抓到預期的"CDC",而改成"([A-Z]+).\1"就只會抓到"CDC"了。
最後誰能幫忙解釋一下"(?>X)",因為我實在分不出來他和(?:X)有什麼差別....
1. Introduction
正規表示式(Regular Expression, 以下簡稱
regexp)在文字處理方面, 已經受到廣泛的應用。而各種程式語言中也幾乎都有提供對 regexp 的支援, 廣受歡迎的 Perl
更是其中的佼佼者。在 Java SDK 1.4 版釋出之前, 若想在 Java 語言中使用 regexp,
就必需依靠由第三方提供之類別函式庫(Third-Party Class Library), 例如 The Apache Jakarta
Project 提供的 Jakarta Regexp, 及 GNU Regex for Java 等. 而 Sun 也終於在 Java SDK
1.4 以來開始於其核心 API 中提供 java.util.regex.Pattern 等相關類別, 以提供C0D; regexp
的支援。本文將會介紹前述的三種 regexp package 之使用方法, 希望能提供讀者在 Java 中使用 Regular
Expression 的指引。注意, 本文中並不會介紹 regexp 的語法, 若要學習 regexp, 請參考附錄。
2. java.util.regex.*
JDK 1.4 中所提供的 regex package 中只有簡單的兩個類別, Pattern 及 Matcher。但這兩個物件已經包含了所有 regexp 的功能, 請看以下的介紹:
2.1 Pattern 與 split()
Pattern 類別並沒有建構式(Constructor), 若要使用此一類別, 可運用 Pattern.compile(String regex) 方法(method)。例:
Pattern p = Pattern.compile("a*b");
注意若傳入的regexp string有錯誤, compile() 會丟出 PatternSyntaxException, 因此必需自行使用try ... catch 加以處理。
產生出 Pattern 物件後, 要如何使用呢? 先看看 Pattern 提供的方法 split()。此一方法可以將輸入字串中依符合Pattern的位置進行分段, 如:
String[] result = p.split("123aba23aabc");
for (int i = 0; i < result.length; i++) {
System.out.println( (i + 1) + ": " + result[i]);
}
輸出的結果為:
1: 123
2: a23
3: c
2.2 Matcher 與 matches()
Regular Expression 的功能當然不只如此, 但是 Pattern 類別中只提供了split(),
若要進行比對(match)及取代(replace)則必需靠 Matcher 類別。例如要檢驗輸入字串是否合於Pattern, 可以使用
Pattern 中的靜態方法 matches:
System.out.println(Pattern.matches("a*b", "aaaaab"));
輸出結果為:
true
此一靜態方法是為了方便使用而提供的簡化方法, 其作用等同以下程式:
Pattern.compile("a*b").matcher("aaaaab").matches();
另外, 要注意的是, matches() 是完整字串的比對,所以 Pattern.matches("a*b",
"aaaaab") 的傳回值為 true 。但是 Pattern.matches("a*b", "aaaaab1") 則會傳回否。因此,
若要在輸入字串中進行部分比對,則必需使用 Matcher 物件中提供的 method。而要如何取得 Matcher 物件呢? 方法如下:
Pattern p = Pattern.compile("a*b");
Matcher matcher = p.matcher("aaaaab");
Matcher 中提供了三種比對方法, 您可以依照實際需要來選擇使用:
- matches: 完整比對, 整個輸入字串必需符合 regexp。例如前例輸入字串 "aaaaab" 完全符合 "a*b", 因此會 matches() 傳回 true.
- lookingAt: 從輸入字串開頭比對。如前例, 若輸入字串改為 "aaaaab1" 則 matches() 會傳回 false, 而 lookingAt() 會傳回true。
- find: 從字串中任意位置開始比對,也就是部分比對。如前例, 若輸入字串改為 "22aaaaab1" 則 matches()及lookingAt()皆傳回 false, 而 find() 則會傳回true。
2.3 replaceFirst(), replaceAll()
除了比對之外, 取代(replace)也是regexp的常見用途之一, 在 Matcher 中也提供了 replaceFirst() 及 replaceAll() 等方法進行取代。如:
Pattern p = Pattern.compile("a*b");
Matcher matcher = p.matcher("123aaaaab456abcdef");
System.out.println(matcher.replaceFirst("_"));
//1
matcher.reset();
//2
System.out.println(matcher.replaceAll("_"));
//3
前例中的 1 會輸出:
123_456abcdef
只將第一個 match 的 pattern 取代為 "_", 而 3 則會輸出
123_456_cdef
將輸入字串中所有合於 pattern 的字串取代為 "_"。
請注意到 2 的部分呼叫了 matcher.reset(), 此一方法可以讓 Matcher 的比對重新開始,
也就是從輸入字串的開頭開始比對。另外, 若在程式中需要以同一個 Pattern 比對不同的輸入字串, 只需使用
reset(<input>) 方法便可以比對新的輸入字串。
2.4 gourp(), start() 及 end()
Matcher還有更進階的用法, 例如群組(Grouping), 在 Matcher 中亦有提供, 請參考以下片段:
Pattern p = Pattern.compile("(\\w+)\\s*=\\s*(\\d+)");
Matcher matcher = p.matcher("abc = 123");
System.out.println("find: " + matcher.find());
System.out.println("groupCount(): " + matcher.groupCount());
//1
for (int i = 1; i <= matcher.groupCount(); i++) {
//2
System.out.println("group(" + i + "):" + matcher.group(i));
System.out.println("start(" + i + "):" + matcher.start(i));
System.out.println("end(" + i + "):" + matcher.end(i));
}
matcher.reset();
System.out.println(matcher.replaceFirst("$2 = $1"));
//3
在 regexp 中, 小括號表示群組, 可以在比對之後, 將合於 pattern 的部分紀錄起來, 以便使用
Matcher 中的 gourp() 及相關方法來應用。前例中的 1 呼叫了 groupCount(), 此處會輸出 2 表示 Pattern
中有兩個群組。迴圈 2 會依序印出各 group 的內容, 結果如下:
group(1):abc
start(1):0
end(1):3
group(2):123
start(2):6
end(2):9
注意此處的迴圈由 1 開始, 因為 gourp(0) 所代表的是整個合於 pattern 的輸入字串, 以前例而言就是 "abc = 123", start(0) 與 end(0) 則分別為 0 與 9。
在 Matcher 提供的取代方法( replaceFirst 與 replaceAll )中, 可以使用"回溯參照", 也就是用 $n 來代表找到的群組編號, 如前例中的 3, 其輸出結果為:
123 = abc
2.5 比對參數旗標 (Matching flags)
熟悉 regexp 的讀者一定會覺得奇怪, 如何建立"與大小寫無關(Case-insensitive)" 的比對樣式呢?
又要怎麼在建立的時候, 指定讓 "." 能符合換行字元呢? 有兩種方式, 第一種方法為在建立 Pattern 物件時傳入比對參數旗標, 如:
Pattern p = Pattern.compile("A.b", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); //1
Matcher matcher = p.matcher("aaa\nbbb");
System.out.println(matcher.replaceAll("_"));
如此一來, 前例的輸出會是: aa_bb
另一種方法, 則是使用"內嵌式旗標(Embedded flags)", 也就是將旗標直接加在 regexp 字串中, 如前例中的 1 可以改為以下的寫法:
Pattern p = Pattern.compile("(?si)A.b");
其中的 ?s 代表單行模式(single-line mode), 也就是 Pattern.DOTALL; 而
?i 則代表與大小寫無關, 即 Pattern.CASE_INSENSITIVE。事實上,Pattern可接受的旗標共有 7 種,
也都有其對應的內嵌式旗標, 請參考 JDK 1.4 文件。
最後, 在 JDK 1.4 中, 之前介紹的 split, matches, replaceAll 及
replaceFirst 等 regexp 功能已經整合到 String 物件中了, 例如要將 "abc123abc" 字串中所有的 "a"
或 "b" 取代為 "c", 可以使用以下敍述:
String tmp = "abc123abc";
String noab = tmp.replaceAll("(a|b)", "c");
若程式中不需要使用到更進階的 regexp 功能, 便可以多加利用在 String 物件中的這些方法。詳細用法請參考 JDK 1.4 文件。
3. To be continue...
以上介紹了 JDK 1.4 中內建的 Regular Expression 類別使用方法, 下期將會介紹 Jakarta Regexp 及 GNU Regex for Java 等套件
4. 附錄:
本文所提到的套件參考文件可以在以下 URL 找到:
- java.util.regex API Documents, http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/package-summary.html
- Regular Expressions for Java, http://www.cacas.org/java/gnu/regexp/
- Jakarta Regexp, http://jakarta.apache.org/regexp/index.html
有關 Regular Expressions 的學習, 可以參考以下文件:
- Mastering Regular Expressions, http://www.oreilly.com/catalog/regex/
- Manual pages of Perl, perlrequick(1), perlretut(1), perlre(1)
- Regular Expression 簡介, http://phi.sinica.edu.tw/aspac/reports/94/94019/
- 一輩子受用的 Regular Expressions -- 兼談另類的電腦學習態度, http://www.cyut.edu.tw/~ckhung/b/gnu/regexp.shtml
- A Tao of Regular Expressions (正規表示式之道) http://sitescooper.org/tao_regexps.html
一、showModalDialog和showModelessDialog有什么不同?
showModalDialog:被打开后就会始终保持输入焦点。除非对话框被关闭,否则用户无法切换到主窗口。类似alert的运行效果。
showModelessDialog:被打开后,用户可以随机切换输入焦点。对主窗口没有任何影响(最多是被挡住一下而以。:P)
二、怎样才让在showModalDialog和showModelessDialog的超连接不弹出新窗口?
在被打开的网页里加上<base target="_self">就可以了。这句话一般是放在<html>和<body>之间的。
三、怎样才刷新showModalDialog和showModelessDialog里的内容?
在showModalDialog和showModelessDialog里是不能按F5刷新的,又不能弹出菜单。这个只能依靠javascript了,以下是相关代码:
<body onkeydown="if (event.keyCode==116){reload.click()}">
<a id="reload" href="filename.htm" style="display:none">reload</a>
将filename.htm替换成网页的名字然后将它放到你打开的网页里,按F5就可以刷新了,注意,这个要配合
<base target="_self">
使用,不然你按下F5会弹出新窗口的。
四、如何用javascript关掉showModalDialog(或showModelessDialog)打开的窗口。
<input type="button" value="关闭" onclick="window.close()">
也要配合<base target="_self">,不然会打开一个新的IE窗口,然后再关掉的。
五、showModalDialog和showModelessDialog数据传递技巧。
(作者语:本来想用一问一答形式来写的,但是我想不出这个怎么问,所以只好这样了。)
这个东西比较麻烦,我改了好几次了不是没办法说明白(语文水平越来越差了),只好用个例子说明了。
例子:
现在需要在一个showModalDialog(或showModelessDialog)里读取或设置一个变量var_name
一般的传递方式:
window.showModalDialog("filename.htm",var_name)//传递var_name变量
在showModalDialog(或showModelessDialog)读取和设置时:
lert(window.dialogArguments)//读取var_name变量
window.dialogArguments="oyiboy"//设置var_name变量
这种方式是可以满足的,但是当你想在操作var_name同时再操作第二个变理var_id时呢?就无法再进行操作了。这就是这种传递方式的局限性。
以下是我建议使用的传递方式:
//不管要操作什么变量,只直传递主窗口的window对象
在showModalDialog(或showModelessDialog)读取和设置时:
alert(window.dialogArguments.var_name)//读取var_name变量
window.dialogArguments.var_name="oyiboy"//设置var_name变量
同时我也可以操作var_id变量
alert(window.dialogArguments.var_id)//读取var_id变量
window.dialogArguments.var_id="001"//设置var_id变量
同样还可以对主窗口的任何对象进行操作,如form对象里的元素。
window.dialogArguments.form1.index1.value="这是在设置index1元素的值"
六、多个showModelessDialog的相互操作。
因为光说很费劲,我就偷点懒,直接用代码来说了,如果不明白的话那就直接来信(oyiboy#163.net(使用时请将#改成@))问我吧。
以下代码的主要作用是在一个showModelessDialog里移动别一个showModelessDialog的位置。
主文件的部份js代码。
var s1=showModelessDialog('控制.htm',window,"dialogTop:1px;dialogLeft:1px") //打开控制窗口
var s2=showModelessDialog('about:blank',window,"dialogTop:200px;dialogLeft:300px") //打开被控制窗口
控制.htm的部份代码。
<script>
//操作位置数据,因为窗口的位置数据是"xxxpx"方式的,所以需要这样的一个特殊操作函数。
function countNumber(A_strNumber,A_strWhatdo)
{
A_strNumber=A_strNumber.replace('px','')
A_strNumber-=0
switch(A_strWhatdo)
{
case "-":A_strNumber-=10;break;
case "+":A_strNumber+=10;break;
}
return A_strNumber + "px"
}
</script>
<input type="button" onclick="window.dialogArguments.s2.dialogTop=countNumber(window.dialogArguments.s2.dialogTop,'-')" value="上移">
<input type="button" onclick="window.dialogArguments.s2.dialogLeft=countNumber(window.dialogArguments.s2.dialogLeft,'-')" value="左移">
<input type="button" onclick="window.dialogArguments.s2.dialogLeft=countNumber(window.dialogArguments.s2.dialogLeft,'+')" value="右移">
<input type="button" onclick="window.dialogArguments.s2.dialogTop=countNumber(window.dialogArguments.s2.dialogTop,'+')" value="下移">
以上关键部份是:
窗口命名方式:var s1=showModelessDialog('控制.htm',window,"dialogTop:1px;dialogLeft:1px")
变量访问方式:window.dialogArguments.s2.dialogTop
这个例子只是现实showModelessDialog与showModelessDialog之间的位置操作功能,通过这个原理,在showModelessDialog之间相互控制各自的显示页面,传递变量和数据等。这要看各位的发挥了。
String strSQL
=
"
DELETE FROM TAB_DESIREMOTOR WHERE DESIREMOTORID IN ( ? )
"
;
ps
=
conn.prepareStatement(strSQL);
java.util.Vector v
=
new
Vector();
v.addElement(
new
Int(
1
));
v.addElement(
new
Int(
2
));
ps.setObject(
1
, v);
count
=
ps.executeUpdate();
MyEclipse 5.0 M2 注册码及下载地址
官方介绍:
The
second milestone release (M2) of MyEclipse 5.0 is now available for
immediate downolad. Please review the special instructions, release
notes and the New and Noteworthy before download. MyEclipse 5.0M2 is
compatible with Eclipse 3.2 release candidates. Please be sure to
install Eclipse 3.2 prior to installation of MyEclipse 5.0M2.
Notably,
the MyEclipse 5.0M2 release integrates the popular Matisse4MyEclipse
Swing UI designer directly into MyEclipse, thereby enabling developers
to easily build sophisticated graphical user interfaces for their
applications. Though Matisse4MyEclipse is now supported on Linux, Mac
users will be unable to utilize the Matisse4MyEclipse, MyUML, and
MyEclipse Image Editor functions due to the long-standing Eclipse
SWT_AWT bug #145890.
MyEclipse Enterprise Workbench 5.0 M2 for Windows 98/2000/XP (7/7/2006) 下载地址:
http://www.myeclipseide.com/Downloads+index-req-getit-lid-59.html
序列号过期时间为2099年12月31日,估计用上5-10年都有可能(就看myeclipse的更新速度了)。
Subscriber: www.1cn.biz
Subscriber Code: jLR8ZC-444-55-4467865481680090
注册成功后会发现:
Subscriber: www.1cn.biz
Product ID: E3MP (MyEclipse Professional Subscription)
License version: 9.99
Full Maintenance Included
Subscription expiration date (YYYYMMDD): 20991231
Number of licenses: Unlimited
Eclipse 3.2多国语言包
下载地址列表:
NLpack1 - German, Spanish, French, Italian, Japanese, Korean, Portuguese (Brazil), Traditional Chinese and Simplified Chinese.
windows OS:
http://ftp.jaist.ac.jp/pub/eclipse/eclipse/downloads/drops/L-3.2_Language_Packs-200607121700/NLpack1-eclipse-SDK-3.2-win32.zip