【Perl】字符串匹配:如何正确匹配出’aaaa’中的3个‘aa’模式?

问题 by Zair

一段Perl的代码,输出结果为2。然而显然在字符串’aaaa’中含有3个’aa’模式。请问如何做到3次匹配?

#!/usr/bin/perl
$a = 'aaaa';
$i ++ while $a =~ /aa/g;
print $i;

我的看法

#!/usr/bin/perl
$a = 'aaaa';
$i ++ while $a =~ /a(?=a)/g;
print $i;

正则本质是状态机一个个consume字符扭转状态,捕获成功第一个aa以后相当于前两个字符都被consume掉从第三个a开始匹配了,所以原来的结果是2,这里用零宽断言让正则去look ahead匹配模式里第二个a而不将其consume掉,从而得到3

编译原理学得不好,解释得有点乱……


图形的力量,感觉比字清楚多了

图片描述

软件工程中的耦合性和解耦合性是什么意思?

问题 by iamzhoug37

看《thinking in java》和《head first 设计模式》中,两本书好多次提到了“耦合性”和“解耦合性”这两个词。一直以来都是模棱两可的,搜了一下,维基百科中的解释太专业化了,我没有看懂,通俗的讲这两个词是什么意思?


谢谢大家的回答. 通过大家的回答, 我对于这两个概念有了初步的了解, 但是估计是我的层次不够吧, 看这两本书还是有难度,而且在实际自己编写代码的时候还是不能很好的运用设计模式的精髓, 不过我会努力的,谢谢大家


我的看法

你正乘坐直升机游览科罗拉多大峡谷,驾驶员——他显然犯了一个错误,在吃鱼,他的午餐——突然呻吟起来,晕了过去。幸运的是,他把你留在了离地面100英尺的地方。你推断,升降杆控制总升力,所以轻轻将其压低可以让直升机平缓降向地面。然而,当你这样做时,却发现生活并非那么简单。直升机的鼻子向下,开始向左盘旋下降。突然间你发现,你驾驶的这个系统,所有的控制输入都有次级效应。压低左手的操作杆,你需要补偿性地向后移动右手柄,并踩右踏板。但这些改变中的每一项都会再次影响所有其他的控制。突然间,你在用一个让人难以置信的复杂系统玩杂耍,其中每一项改变都会影响所有其他的输入。你的工作负担异常巨大:你的手脚在不停地移动,试图平衡所有交互影响的力量。

——《程序员的修炼之道》 我认为所有程序员都应该看,而且每年都应该重新看一遍的书


php两种封装类的优缺点?

问题 by tiyee

php很多内置的类或扩展类比较粗糙,需要人为的封装一遍,于是有了两种封装方式, 1直接继承 2内部实例化

如redis类, 可以

namespace lib
class redis extends \Redis {}

也可以

namespace lib
class redis {
    private $_redis = null;
    public function __construct() {
        $this->_redis = new \Redis()
    }
}

第一种方法的优点是方便,无须把所有的方法重写一遍,但是不太好统一捕捉异常, 第二种就是麻烦些,需要重写一遍所有的方法,(虽然可以用魔术方法),捕捉异常方便些。 大家用的哪种?为什么呢?


我的看法

继承

继承的特点有

  • ✔实现成本低
  • ✔调用者可以沿用原有的接口使用,学习成本低
  • ✔原有的功能无需任何代码如常工作
  • ✘无法隐藏或改变原有的功能

    • 其实你_可以_这么做,就好像你确实_可以_用铁丝去捅插座眼一样
    • 改变输入、改变输出、改变行为都属于改变功能,比如原来抛的异常现在不抛了,原来return false现在变异常了,原来输入的是青椒现在变牛肉了等等
  • ✘正交性弱,没有做到屏蔽父类的依赖,需要更换父类的时候显得脆弱

常见的合适的应用有

  • 增加日志记录等不影响原有逻辑的“旁路逻辑”
  • 增加一些方法,比如原有的某一些方法a()b()c()总是连续一起调用,增加一个doABC()方法

    • 仅限简单的少量的方法,如果要加复杂的功能或者大量的方法,还是建议用组合
  • 增加一些静态/工厂方法,比如new Redis(ip, port) => OurRedis::getInstance()

一句话说就是原有行为不变,is-a的场景用继承。

组合

组合的特点有

  • ✘实现成本略高,创建对象的过程可能会变复杂
  • ✘调用者需要理解新的接口
  • ✘需要转发才能让原有的功能工作
  • ✔很容易隐藏/屏蔽原有的部分功能
  • ✔正交性强,可以通过更换内部的对象适配不同的情况而保持外部接口不变

常见的合适的应用有

  • 一切涉及改变行为的需求
  • 未来依赖会变的场景,比如redis会变成memcache,或者mysql会变mariadb之类
  • 需要屏蔽细节的场景,比如Session Cache等需求确实用到redis,但对外肯定要屏蔽“这是个redis实现的session”。否则恐龙会出现在你背后把你脑袋咬掉

一句话就是某个功能依赖另一个功能,use-ahas-a的场景用组合


偏题,predis用起来还不错,可以一试


这是我在 SegmentFault 上的问题回答选编,遵循CC BY-SA 3.0 CN 分享

题图:万智【接踵而至】

©mcfog All rights reserved.