今天看了一个关于正则的帖子: 请解释一下正则的相关内容
在帖子中, 从火龙果的回答中学习了很多东西, 里面火龙果在7楼提到了匹配时的"多项授权"(我不知道这该叫什么名字).
Pattern pattern = Pattern.compile(regex, Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
这里要讨论的其实是和正则没有多少关系的内容.
下面是java.util.regular.Pattern 源码中定义的一些常量, 都是十六进制的值.
把这些值转换成二进制
前面的二十四位, 我们先不考虑, 只考虑后面的八位, 我们可以发现, 其实, 每个常量占了一位.
用过linux的朋友可能知道linux的文件授权中有777这样的授权, 分别对创建者, 拥有者, 拥有者同组用户进行授权.
这里是一致的思想. 这种授权和认证的方式, 使用每一位代表一个操作. 然后通过位运算进行授权和认证
引用火龙果给出的代码Pattern pattern = Pattern.compile(regex, Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
Pattern.DOTALL | Pattern.CASE_INSENSITIVE 实际上就是
00000000 00000000 00000000 00100000 | 00000000 00000000 00000000 00000010
与运算得到的结果是(假定为a):00000000 00000000 00000000 00100010
这样, 在正则的匹配过程中, 它在获取用户设置了要使用哪些常量代表的特性的时候, 比如CASE_INSENSITIVE这个吧, 它的有意义的位是右数第二位, 那我们创建一个临时的int变量1, 左移1位, 就可以得到00000000 00000000 00000000 00000010,
将上一次运算的结果(a)00000000 00000000 00000000 00100010 和 00000000 00000000 00000000 00000010做一次与运算, 与运算中, 0可以屏蔽对方的当前位, 1可以获取对方的当前位, 那我们的结果(假定为b)就是00000000 00000000 00000000 00000010, 只要结果b不为0那么, 这一个操作的授权就是有的....
下面, 我们在来看看linux的文件授权认证体系(或许不是这样做的, 原理是这样):
假定: 777中第一个数字代表创建者授权, 第二个数字代表拥有者授权, 第三个数字代表拥有者同组用户的授权.
为了方便, 我们以对创建者授权认证为例, 这里使用3位的二进制表示.(由于前面的都是0, 所以, 讨论也没有意义, 反而像上面一样增加理解难度)
linux中, 权限有读, 写, 执行三种, 具体的顺序我也忘了, 假定顺序就是读写执行吧.
那么, 我们限定: 一个3位的二进制数来表示权限, 从右向左, 第一位代表读, 第二位代表写, 第三位代表执行.
101就代表可读, 可执行, 不可写
每种操作, 都有了对应的位, 我们记录下来这一点
r = 1 读是右数第一位
w = 2 写是右数第二位
e = 3 执行是右数第三位
初始的权限是000, 也就是什么权限都没有.
现在, 我们要设置让权限变成可写
1. 创建临时变量tmp = 1
2. tmp 左移n-1位, n就是上面给出的为数, 因为左移n-1位之后, 1所在的位就是代表那种操作的位.(这里可以考虑优化了吧. 呵呵, 上面的r=1, w=2, e=3可以改造成r=0, w=1, e = 2, 就可以让我们在这里的移位之前不用再多一次减操作了) 这一步得到的结果是tmp变成了010
3. 用初始授权和tmp进行或运算, 将结果赋予权限. 结果是010, 此时, 我们可以看到, 这个文件的创建者就有了可以写的授权了.
然而, 问题在于, 授权成功之后, 我们的到的010不是二进制表示, 它还是int型的2, 那么, 我们就需要认证
现在我们要认证2这个授权中我们有没有执行的权限.
2 = 010
对上面的那些预定义进行一些改造:
r = 0 读 不需要左移
w = 1 写 需要左移一位
e = 2 执行 需要左移二位
1. 创建一个临时变量tmp = 1
2. 我们要认证执行, 那么, tmp左移2位, 得到100
3. tmp和授权码进行与运算, 100 & 010 = 000, 结果是0, 我们的创建者没有可执行这个授权.
对于linux的文件授权, 有一种说法是r, w, e分别就是1, 2, 4(这里是假设, 具体的顺序我不知道), 有哪个权限, 加上对应的数字就行了.
这种说法也是正确的, 但是, 究其底层, 还是基于位运算的, 因为: 1=001, 2=010, 4=100.