JavaScript大杂烩8 - 理解文本解析的"黄金搭档"

文本解析"黄金搭档" - String与RegExp对象

  文本解析是任何语言中最常用的功能,JavaScript中也是一样,而正则表达式作为最常用的方式,JavaScript也同样是支持的,下面就来看看字符串对象与正则表达式对象的配合。

字符串的恒定性

  在正式开始讨论字符串对象的成员之前,我们需要了解一点,那就是:与C#一样,JavaScript
的字符串是不可变的(immutable),String对象定义的方法都不会改变字符串的内容。像toUpperCase这样的方法,返回的是全新的字符串,而不是修改原始字符串。

String对象

  字符串对象提供了对字符串的各种操作,这些操作可以分为这么几类:

1. 字符串的修改方法:

concat:连接字符串
slice,substr,substring:获取子串
slice,substring和 substr(不建议使用,ECMAscript 因为没有对该方法进行标准化)都可返回字符串的指定部分。slice比substring要灵活一些,因为它允许使用负数作为参数,除了这一点其它都是一样的。
split:拆分字符串为数组
toLowerCase,toUpperCase:转换大小写

直接看例子:


var firstName = ‘Frank ‘;
var secondName = ‘Dong‘;
var name = firstName.concat(secondName);
// 使用加号似乎更简洁
var name1 = firstName + secondName;
alert(name);
alert(name.slice(6)); // Dong
alert(name.slice(6,7)); // D
alert(name.substring(6)); // Dong
alert(name.substring(6,7)); // D
// 拆分为单词
alert(name.split(‘ ‘)); //Frank,Dong
// 字符串转成字符数组的简便方式
alert(name.split(‘‘)); //F,r,a,n,k,D,o,n,g
alert(name.toLowerCase()); // frank dong
alert(name.toUpperCase()); // FRANK DONG

2. 字符串的格式化方法:

anchor,link,blink,big,small,bold,italics,strike,sub,sup:包装成特定的元素或增加特定的样式
fontcolor,fontsize:添加字体信息
fixed:转换成打印机格式

这个不多说了,只需要看一个例子就可以了:

var str = ‘Frank Dong!‘;
alert(str.strike());

运行一下就可以看到包装后的html元素。

3. 字符串的检索方法:

charAt:获取字符
indexOf,lastIndexOf:检索子串的位置

看个简单的例子:

var str = ‘Frank Dong!‘;
alert(str.charAt(0));
alert(str.indexOf(‘Dong‘));
alert(str.lastIndexOf(‘n‘));

这里还有几个重量级的方法:

match,replace,search:检索和替换子串

这一组方法比较特别,这3个方法再加上前面的split方法是支持正则表达式的,功能十分强大,在总结它们之前先来看一下正则表达式对象。

RegExp对象

  在JavaScript中使用正则表达式很简单,看一下定义正则表达式对象的语法:


// 字面量方式
/pattern/attributes
// new方式
new RegExp(pattern, attributes);
参数 pattern 是一个字符串,指定了正则表达式的模式或其他正则表达式。
参数 attributes 是一个可选的字符串,包含属性 "g"、"i" 和 "m",分别用于指定全局匹配、区分大小写的匹配和多行匹配。ECMAScript 标准化之前,不支持 m 属性。如果 pattern 是正则表达式,而不是字符串,则必须省略该参数。

  经过这种方式,我们就定义了一个正则表达式对象,有了对象我们就可以使用它的方法了,该对象有下列方法:

1.
compile:编译正则表达式,通常是在修改了表达式的pattern以后执行这个方法让新pattern生效。


var str = "Frank0 Dong0 Frank1 Dong1";
var patt = /Frank/g;
var str2 = str.replace(patt,"FF");
alert(str2);
patt = /Dong/g;
patt.compile(patt);
str2 = str.replace(patt,"DD");
alert(str2);

  这个例子中就用到了支持正则表达式的string方法replace,这个方法会替换所有满足条件的文本。

  在这里我们再回头看看string中支持正则表达式的其它3个方法:match,split,search,看个例子就可以了:


var str = "Frank0 Dong0 Frank1 Dong1";
var patt = /Frank\d/g;
// 总是从开始查找第一个匹配的文本,然后返回其索引值
var result = str.search(patt);
alert(result);
// 拆成数组
result = str.split(‘ ‘);
for (var i = 0, len = result.length; i < len; i++) {
alert(result[i]);
}
// 查找所有匹配的文本
result = str.match(patt);
for (var i = 0, len = result.length; i < len; i++) {
alert(result[i]);
}

2.
test:检索字符串中是否存在与pattern匹配的文本。

  匹配到则返回true否,则返回false,看个小例子:

alert(/[abc]/.test(‘a‘)); //true

3.
exec:检索字符串中与pattern匹配的文本。

  这个方法返回一个数组,其中存放一次匹配的结果。如果未找到匹配,则返回值为
null。

  如果找到匹配的话。结果数组的第0个元素是与正则表达式相匹配的文本,从第1个元素开始是与各个分组相匹配的文本。如果一个字符串中有多个与pattern匹配的文本的话,则需要循环的调用这个方法去找到所有的匹配(pattern对象自己会维护上次查找后的位置,这样循环的时候就会从正确的位置开始),看个例子:

var str = "Frank0 Frank1";
var patt = /Frank\d/g;
var result;
while ((result = patt.exec(str)) != null) {
alert(result);
}

  这里特别需要注意的是g属性,有没有这个属性对很多的方法结果都有影响,比如正则表达式对象的exec方法,字符串对象的match方法等,没有这个属性的时候总是匹配第一次出现的文本,只有加上了这个属性,它们才会正确的去匹配所有出现的文本,所以一般来说加上g属性好处还是很多的

  此外由于i属性是设置忽略大小写的,大家需要的时候别忘了加上这个属性。

  需要补充的是,正则表达式的预定义类(\d,\D,\W等),分组(小括号括起来的),量词(+*.?),边界(^$),反向引用在JavaScript中都是支持的,可以量才录用啊。

  使用正则表达式,可以完成很多JavaScript的String对象无法完成的任务,比如移除空格的Trim方法等等,下面是网上一位仁兄的杰作:


//获取字符数组
String.prototype.toCharArray = function()
{
return this.split(‘‘);
}
//获取N个相同的字符串
String.prototype.repeat = function(num)
{
var tmpArr = [];
for(var i=0; i<num; i++) tmpArr.push(this);
return tmpArr.join(‘‘);
}
//逆序
String.prototype.reverse = function()
{
return this.split(‘‘).reverse().join(‘‘);
}
//测试是否是数字
String.prototype.isNumeric = function()
{
var tmpFloat = parseFloat(this);
if(isNaN(tmpFloat)) return false;
var tmpLen = this.length - tmpFloat.toString().length;
return tmpFloat + "0".repeat(tmpLen) == this;
}
//测试是否是整数
String.prototype.isInt = function()
{
if(this == "NaN") return false;
return this == parseInt(this).toString();
}
// 合并多个空白为一个空白
String.prototype.resetBlank = function()
{
return this.replace(/s+/g,‘ ‘);
}
// 除去左边空白
String.prototype.trimL = function()
{
return this.replace(/^s+/g,‘‘);
}
// 除去右边空白
String.prototype.trimR = function()
{
return this.replace(/s+$/g,‘‘);
}
// 除去两边空白
String.prototype.trim = function()
{
return this.replace(/(^s+)|(s+$)/g,‘‘);
}
// 保留数字
String.prototype.getNum = function()
{
return this.replace(/[^d]/g,‘‘);
}
// 保留字母
String.prototype.getEn = function()
{
return this.replace(/[^A-Za-z]/g,‘‘);
}
// 保留中文
String.prototype.getCn = function()
{
return this.replace(/[^u4e00-u9fa5uf900-ufa2d]/g,‘‘);
}
// 得到字节长度
String.prototype.getRealLength = function()
{
return this.replace(/[^x00-xff]/g,‘--‘).length;
}
// 从左截取指定长度的字串
String.prototype.left = function(n)
{
return this.slice(0,n);
}
// 从右截取指定长度的字串
String.prototype.right = function(n)
{
return this.slice(this.length-n);
}
// HTML编码
String.prototype.htmlEncode = function()
{
var re = this;
var q1 = [/x26/g,/x3C/g,/x3E/g,/x20/g];
var q2 = [‘&‘,‘<‘,‘>‘,‘ ‘];
for(var i=0; i<q1.length; i++) re = re.replace(q1[i],q2[i]);
return re;
}
// Unicode转化
String.prototype.ascW = function()
{
var strText = ‘‘;
for (var i=0; i<this.length; i++) strText += ‘&#‘ + this.charCodeAt(i) + ‘;‘;
return strText;
}

  经典,可以收藏了。

  最后以一组最常用的正则表达式结束正则表达式:

匹配中文字符的正则表达式: [\u4e00-\u9fa5]
匹配HTML标记的正则表达式:/< (.*)>.*|< (.*) />/
匹配首尾空格的正则表达式:(^s*)|(s*$)
匹配Email地址的正则表达式:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*
匹配网址URL的正则表达式:http://([w-]+.)+[w-]+(/[w- ./?%&=]*)?

  除了这里讨论的这些核心的对象外,JavaScript还提供了一些辅助的对象,提供数学运算的Math对象(正/余弦,正/余切,指/对数,随机数,取整等功能),处理日期的Date对象(创建日期并以各种格式输出),这些对象都很简单,就不多说了。

最佳参考:

W3C的教程是无法替代的,相当详实,内置对象的所有方法都能找到详尽的说明:http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp

JavaScript大杂烩8 - 理解文本解析的"黄金搭档",布布扣,bubuko.com

时间: 2024-08-24 14:03:11

JavaScript大杂烩8 - 理解文本解析的"黄金搭档"的相关文章

JavaScript大杂烩12 - 理解Ajax

AJAX缘由 再次谈起这个话题,我深深的记得就在前几年,AJAX被炒的如火如荼,就好像不懂AJAX,就不会Web开发一样.要理解AJAX为什么会出现,就要先了解Web开发面临的问题. 我们先来回忆一下Web页面的申请过程,这个咱们在第一篇中就介绍过了:Web页面开发就是在无连接和无状态的HTTP协议上管理页面的状态.每次申请页面的时候,服务器都会返回完整的HTML文本(当然还有其他的文本文件),浏览器就负责解析这个文本并在浏览器中显示. 在这个过程中,不管当前页面的内容是不是都变化了,服务器都会

JavaScript大杂烩9 - 理解BOM

毫无疑问,我们学习JavaScript是为了完成特定的功能.在最初的JavaScript类型系统中,我们已经分析过JavaScript在页面开发中充当着添加逻辑的角色,而且我们知道JavaScript不仅仅包含基本的语法规范.下面我们就重点看一下JavaScript在页面中干的那些事.总的来说,JavaScript在页面端就干两件事:操作DOM与操作BOM (当然了向Server获取数据也是它的工作,不过获取到数据后还是回来干这两件事,大家对JavaScript最直接的印象应该就是各种光怪陆离的

JavaScript大杂烩6 - 理解JavaScript中的this

在JavaScript开发中,this是很常用的一个关键字,但同时也是一个很容易引入bug的一个关键字,在这里我们就专门总结一下页面中可能出现的this关键字(包括几种在其他页面文件中出现的this). JavaScript中的this关键字通常只使用在函数中,它指向当前函数的调用者,这是this关键字的本质,所有的使用方式都是围绕这个展开的,让我们来看一下在各种性质的函数中this的用法.1. 在对象的函数中使用this var person = { name: 'Frank', say: f

JavaScript大杂烩7 - 理解内置集合

JavaScript内置了很多对象,简单的类型如String,Number,Boolean (相应的"值类型"拥有相同的方法),复杂一点的如Function,Object,Array,它们支撑起来JavaScript编程的基石.由于Number与Boolean很简单,这里就不多说了,下面着重介绍其他的内置对象. 万物之源 - Object对象 JavaScript是单根的,唯一的根就是Object对象,这个对象提供了几个还是不错的方法,值得了解一下. 1. hasOwnProperty

JavaScript大杂烩1 - 理解JavaScript的类型系统

随着硬件水平的逐渐提高,浏览器的处理能力越来越强大,本人坚信,客户端会越来越瘦,瘦到只用浏览器就够了,服务端会越来越丰满:虽然很多大型的程序,比如3D软件,客户端仍然会存在,但是未来的主流必将是浏览器,也就是Web程序/网站. Web前端开发模式:Thinking in "DIV + CSS + JS (JavaScript)" 任何面向用户的程序,最终都表现为3个部分:界面,逻辑,数据.而经过几十年的编程实践,大家都发现,当把这3个部分以弱耦合的形式结合起来的时候,开发的灵活性和效率

JavaScript大杂烩4 - 理解JavaScript对象的继承机制

面向对象之继承 JavaScript是单根的面向对象语言,它只有单一的根Object,所有的其他对象都是直接或者间接的从Object对象继承(没有指定父类的对象,都被认为是从Object继承的). 在前面我们讨论了面向对象的封装性,在最后的地方也谈到了JavaScript的继承是通过原型和原型链实现的,下面我们就详细的展开这个问题:JavaScript到底是如何实现继承的? 继承的本质 继承的本质是重用,从语法上来讲,继承就是"D是B"的描述,其中B是基类,描述共性,D是子类,描述特性

JavaScript大杂烩2 - 理解JavaScript的函数

JavaScript中的字面量 书接上回,我们已经知道在JavaScript中存在轻量级的string,number,boolean与重量级的String,Number,Boolean,而且也知道了之间的区别.这里补充一点,直接使用字面量定义的变量都是属于前一种类型,例如: var name = 'Frank'; 此外大多数的内置操作返回的也都是前一种类型,这是必须的. function是第一等公民 与别的语言不同,在JavaScript中,函数是作为数据类型存在的,所以函数具有数据的静态行为.

JavaScript的工作原理:解析、抽象语法树(AST)+ 提升编译速度5个技巧

这是专门探索 JavaScript 及其所构建的组件的系列文章的第 14 篇. 如果你错过了前面的章节,可以在这里找到它们: JavaScript 是如何工作的:引擎,运行时和调用堆栈的概述! JavaScript 是如何工作的:深入V8引擎&编写优化代码的5个技巧! JavaScript 是如何工作的:内存管理+如何处理4个常见的内存泄漏 ! JavaScript 是如何工作的:事件循环和异步编程的崛起+ 5种使用 async/await 更好地编码方式! JavaScript 是如何工作的:

JavaScript大杂烩5 - JavaScript对象的若干问题

1. 类型检查:instanceof与typeof 这是两个相似的操作符,instanceof用于检测函数的实例类型,主要是在面向对象编程中检查new出来的对象类型,需要注意instanceof是检查function对象的,前面实现的复制继承中的例子就不适用于使用instanceof来检查继承关系了.typeof,它用于检测变量的类型,在实际情况中应用的不是很多,稍微了解一下就可以了. 在使用typeof之前,有一点需要确认,那就是string与String不是同一个类型,这个不用多说了,我们前