正则表达式有什么用呢?
查找和替换!!
在 js 中共有六个方法可以供我们使用:
test,exec,match,search,split 和 replace
个人看来 replace 是最重要的, 其地位相当于数组中的 splice 和 reduce 方法.
也就是说, 只用它, 就可以做到其他 api 的能做到的事情.
相当于万能方法, 所以需要重点掌握.
查找和替换, 两个词语虽然简单, 但是包络万象啊.
正则作用也可以细分: 提取, 验证, 替换, 切分.
上述说法来自于正则指引, 那个 "切分", 咋回事? 就是使用 split 啦...
本系列(正则表达式研究), 到目前为止, 大部分基础内容都已经讲完.
但是, 但是, 并没有完结, 还有几个点, 后续也会追加进来.
不过, 之前讲到的知识点, 足以应付大部分应用了.
从本篇开始先弄几篇应用, 来让我们体会体会正则的强大!!
案例都是哪来的?
呵呵, 这些案例都不是我原创的, 也是拿来主义(会标明出处的).
ok, 趁着大伙放假, 偷偷写几篇, 哈哈.
谁看谁知道.
本文下面的几个正则例子, 均出自JavaScript 忍者秘籍(部分代码我会悄悄地改改, 哈哈).
1. 通过 className 来获取 dom 元素(实现类似 getElementsByClassName 的 api)
html 代码
- <div class="ok high"></div>
- <p class="high">1111</p>
- <p class="high ok yaya">2222</p>
- <div class="ok"></div>
- <script>
- function findClassInElements(className, type) {
- var elements = document.getElementsByTagName(type || '*');
- var regex = new RegExp("(^|\\s)" + className + "(\\s|$)");
- var result = [];
- for (var i = 0, length = elements.length; i <length; i++) {
- var element = elements[i];
- if (regex.test(element.className)) {
- result.push(element)
- }
- }
- return result;
- }
- </script>
- <script>
- var oks = findClassInElements('ok');
- oks.forEach(function(item) {
- item.style.height = '20px';
- item.style.background = "gray";
- });
- var highp = findClassInElements('high', 'p');
- highp.forEach(function(item) {
- item.style.height = '30px';
- });
- </script>
总体思路很简单, 找到所有的 dom 元素, 逐个过滤(使用 test).
问题是如何构建所需的正则, 比如我要找到拥有'high'这个 class 的元素.
代码中正则构造是:/(^|\s)high(\s|$)/,
也就是说 high 两边, 要么是空格, 要么是开头或者结尾.
因为函数运行的每次的 className 都不一样, 因此每次正则也不一样,
所以正则需要通过字符串拼接, 然后 new 构造函数来生成.
注: 此案例是考察 js 中正则声明问题. 可以使用构造函数式, 也可以使用字面量.
2. 提取透明度值
html 代码
- <div style="opacity:0.5;filter:alpha(opacity=50)"><div>
- <script>
- function getOpacity(element) {
- var filter = element.style.filter;
- if (!filter) {
- return element.style.opacity;
- } else {
- if (filter.indexOf("opacity=")> 0) {
- var match = filter.match(/opacity=([^\)]+)/)[1];
- return parseFloat(match / 100) + '';
- } else {
- return '';
- }
- }
- }
- </script>
- <script>
- var target = document.getElementsByTagName('div')[0];
- var opacity = getOpacity(target);
- alert(opacity);
- </script>
提出核心代码:
javascript 代码
- var string = "opacity:0.5;filter:alpha(opacity=50)";
- var match = string.match(/opacity=([^\)]+)/);
- console.log(match)
正则的提取功能. 需要使用括号的捕获功能.
怎么用正则来匹配 alpha(opacity=50)里面的 opacity=50 呢?
/opacity=\d+/ 即可描述, 因为要提取, 所以要添加括号,
所以变成 / opacity=(\d+)/, 上述代码中, 考虑的事情比较多一些, 因为 alpha(opacity=50)这个整体是 filter 属性的值, 是用户输入的.
50 那个位置, 用户可能会输入非数字的. 因此是任意字符都可以的, 但又不能是 ")",
不然, 括号里捕获的字符将会是 "50)". 所以代码中正则用的是([^)]+)
注: 书上的正则是 / opacity=([^)]+)/, 这么写并没有错.
个人觉得 ")" 是元字符, 为了形成良好习惯, 要转义.
而有一些字符虽然是元字符比如 "!" 和 "=", 只有在特殊的结构中才有意义 (= 只有在正向前查找(?=p) 中, 才有意义), 可以不用转义. 当然, 转了也没错.
3. 将中横线字符串转换成驼峰拼写法
javascript 代码
- function hyphenToCamel(string) {
- return string.replace(/-(\w)/g, function(match, letter) {
- return letter.toUpperCase();
- })
- }
- var result = hyphenToCamel('background-color');
- console.log(result);
正则的替换功能, 把 - c 替换成 C.replace 的参数 match 是整个正则匹配的字符串, letter 是括号分组捕获到的内容.
4. 压缩查询字符串的技术
javascript 代码
- function compress(source) {
- var keys = {};
- source.replace(/([^=&]+)=([^&]*)/g, function(full, key, value) {
- keys[key] = (keys[key] ? keys[key] + ',' : '') + value;
- return '';
- });
- var result = [];
- for (var key in keys) {
- result.push(key + '=' + keys[key]);
- }
- return result.join('&');
- }
- var result = compress("a=1&b=2&a=3&b=4");
- console.log(result);// a=1,3&b=2,4
典型的利用 replace 来做提取功能. 关键是正则怎么写, 才能提取相应的 key 和 value 呢?/([^=&]+)=[^&]/ 中,[^=&]+ 用来描述 key,[^&]用来描述 value,value 可以没值, 因此用的是, 为啥不用 [^=&] 来说描述 value 呢? 难道, query 字符串可以是这样的吗: a===&b=3. 这个我也不清楚..
上述算法, 可以改成如下的(replace 第二参数函数, 写不写返回值都不打紧)
javascript 代码
- function compress(source) {
- var keys = {};
- source.replace(/([^=&]+)=([^&]*)/g, function(full, key, value,i,s) {
- keys[key] = keys[key] || [];
- keys[key].push(value);
- });
- var result = [];
- for (var key in keys) {
- result.push(key + '=' + keys[key].join(','));
- }
- return result.join('&');
- }
- var result = compress("a=1&b=2&a=3&b=4");
- console.log(result);// a=1,3&b=2,4
5.trim 方法
javascript 代码
- function trim(str) {
- return (str || '').replace(/^\s+|\s+$/g,'');
- }
- var result = trim('#id div.class');
- console.log(result);
使用双重 replace:
javascript 代码
- function trim(str) {
- return (str || '').replace(/^\s\s*/,'').replace(/\s\s*$/, '');
- }
- var result = trim('#id div.class');
- console.log(result);
不要问我,/^\s\s*/ 和 /^\s+/ 有什么区别, 我会告诉你 / 1111 / 和 / 1{4}/ 和 / 1{2}1{2}/ 是一回事...
正则相关系列传送门 https://notes/17398/e2f4cab17533ec963352f9ae3c715c79.html
来源: http://www.qdfuns.com/article/17398/c7ffa721333e87886739a0f24cf26571.html