blogjava-凯发k8网页登录http://www.blogjava.net/zhyiwww/category/12353.htmlzhyiwwwzh-cnthu, 29 mar 2007 09:17:20 gmtthu, 29 mar 2007 09:17:20 gmt60三个数能组成三角形的充分必要条件http://www.blogjava.net/zhyiwww/archive/2007/03/29/107202.htmlzhyiwwwzhyiwwwthu, 29 mar 2007 05:32:00 gmthttp://www.blogjava.net/zhyiwww/archive/2007/03/29/107202.htmlhttp://www.blogjava.net/zhyiwww/comments/107202.htmlhttp://www.blogjava.net/zhyiwww/archive/2007/03/29/107202.html#feedback0http://www.blogjava.net/zhyiwww/comments/commentrss/107202.htmlhttp://www.blogjava.net/zhyiwww/services/trackbacks/107202.html 【题说】 1996 年北京市赛高一复试题 5

【证】( 1 )不妨设 a b c a 为最大.

因为 2 a 2 b 2 b 2 c 2 c 2 a 2 - a 4 b 4 c 4 = 2ab 2 - a 2 b 2 -c 2 2 0

所以

2ab a 2 b 2 -c 2

a 2 b 2 c 2 = a 2 b 2 -c 2 2c 2 2ab 2c 2

2 ab bc ca

2 )( * )的逆命题:设 a b c 是非负实数.如果 a 2 b 2 c 2 2 ab bc ca ),

a 4 b 4 c 4 2 a 2 b 2 b 2 c 2 c 2 a 2

这逆命题不真,例如 a=4 b=c=1

a 2 b 2 c 2 =2 ab bc ca =18

a 4 b 4 c 4 =258 2 a 2 b 2 b 2 c 2 c 2 a 2 =66

【评注】 a 4 b 4 c 4 2 a 2 b 2 b 2 c 2 c 2 a 2 )是 a b c 构成三角形的充分必要条件 ,而且在构成三角形时,设三角形面积为δ,则

16 δ 2 =2 a 2 b 2 b 2 c 2 c 2 a 2 -a 4 -b 4 -c 4 0

sqrt.png

这是我在找资料的时候偶尔看到的,觉得也许以后有用得到的时候,所以就摘录了下来。


zhyiwww 2007-03-29 13:32
]]>
b树算法(转载)http://www.blogjava.net/zhyiwww/archive/2006/07/07/57174.htmlzhyiwwwzhyiwwwfri, 07 jul 2006 10:24:00 gmthttp://www.blogjava.net/zhyiwww/archive/2006/07/07/57174.htmlhttp://www.blogjava.net/zhyiwww/comments/57174.htmlhttp://www.blogjava.net/zhyiwww/archive/2006/07/07/57174.html#feedback1http://www.blogjava.net/zhyiwww/comments/commentrss/57174.htmlhttp://www.blogjava.net/zhyiwww/services/trackbacks/57174.html b树算法
作者:icephoton  


这个结构一般用于的索引,综合效率较高。
另外还有一种与此类似的树结构叫b 树,像 berkerly db , sqlite , mysql 都使用了b 树算法处理索引。
这两种处理索引的数据结构的不同之处:
1。b树中同一键值不会出现多次,并且它有可能出现在叶结点,也有可能出现在非叶结点中。而b 树的键一定会出现在叶结点中,并且有可能在非叶结点中也有可能重复出现,以维持b 树的平衡。
2。因为b树键位置不定,且在整个树结构中只出现一次,虽然可以节省存储空间,但使得在插入、删除操作复杂度明显增加。b 树相比来说是一种较好的折中。
3。b树的查询效率与键在树中的位置有关,最大时间复杂度与b 树相同(在叶结点的时候),最小时间复杂度为1(在根结点的时候)。而b 树的时候复杂度对某建成的树是固定的。

如果想自己做个小型,可以参考一下下面给出的b树算法的实现,可能会对你有所帮助。

  其中的注册很详细,不用再多说了。

/* btrees.h */
/*
* 平衡多路树的一种重要方案。
* 在 1970 年由 r. bayer 和 e. mccreight 发明。
*/
#define m 1
/* b 树的阶,即非根节点中键的最小数目。
* 有些人把阶定义为非根节点中子树的最大数目。
*/
typedef int typekey;
typedef struct btnode {    /* b-tree 节点 */
    int d;    /* 节点中键的数目 */
    typekey k[2*m];    /* 键 */
    char *v[2*m];    /* 值 */
    struct btnode *p[2*m 1];    /* 指向子树的指针 */
} node, *btree;
/*
* 每个键的左子树中的所有的键都小于这个键,
* 每个键的右子树中的所有的键都大于等于这个键。
* 叶子节点中的每个键都没有子树。
*/

/* 当 m 等于 1 时也称为 2-3 树
*     ---- ----
*    | k0 | k1 |                    
*   - ---- ---- ---
*  | p0 | p1 | p2 |
*   ---- ---- ----
*/
extern int btree_disp; /* 查找时找到的键在节点中的位置 */
extern char * insvalue; /* 与要插的键相对应的值 */

extern btree search(typekey, btree);
extern btree insert(typekey,btree);
extern btree delete(typekey,btree);
extern int height(btree);
extern int count(btree);
extern double payload(btree);
extern btree deltree(btree);
/* end of btrees.h */

/*******************************************************/

/* btrees.c */
#include
#include
#include "btrees.h"

btree search(typekey, btree);
btree insert(typekey,btree);
btree delete(typekey,btree);
int height(btree);
int count(btree);
double payload(btree);
btree deltree(btree);

static void internalinsert(typekey, btree);
static void insinnode(btree, int);
static void splitnode(btree, int);
static btree newroot(btree);

static void internaldelete(typekey, btree);
static void joinnode(btree, int);
static void moveleftnode(btree t, int);
static void moverightnode(btree t, int);
static void delfromnode(btree t, int);
static btree freeroot(btree);

static btree delall(btree);
static void error(int,typekey);

int btree_disp; /* 查找时找到的键在节点中的位置 */
char * insvalue = null; /* 与要插的键相对应的值 */
static int flag; /* 节点增减标志 */
static int btree_level = 0; /* 多路树的高度 */
static int btree_count = 0; /* 多路树的键总数 */
static int node_sum = 0;  /* 多路树的节点总数 */
static int level; /* 当前访问的节点所处的高度 */
static btree newtree; /* 在节点分割的时候指向新建的节点 */
static typekey inskey; /* 要插入的键 */

btree search(typekey key, btree t)
{
    int i,j,m;
    level=btree_level-1;
    while (level >= 0){
        for(i=0, j=t->d-1; i t->k[m])?(i=m 1):(j=m));
        if (key == t->k [ i ]){
            btree_disp = i;
            return t;
        }
        if (key > t->k [ i ]) /* i == t->d-1 时有可能出现 */
            i ;
        t = t->p[ i ];
        level--;
    }
    return null;
}

btree insert(typekey key, btree t)
{
    level=btree_level;
    internalinsert(key, t);
    if (flag == 1)  /* 根节点满之后,它被分割成两个半满节点 */
        t=newroot(t);    /* 树的高度增加 */
    return t;
}

void internalinsert(typekey key, btree t)
{
    int i,j,m;

    level--;
    if (level < 0){ /* 到达了树的底部: 指出要做的插入 */
        newtree = null; /* 这个键没有对应的子树 */
        inskey = key; /* 导致底层的叶子节点增加键值 空子树对 */
        btree_count ;
        flag = 1; /* 指示上层节点把返回的键插入其中 */
        return;
    }
    for(i=0, j=t->d-1; i t->k[m])?(i=m 1):(j=m));
    if (key == t->k[ i ]) {
        error(1,key); /* 键已经在树中 */
        flag = 0;
        return;
    }
    if (key > t->k[ i ]) /* i == t->d-1 时有可能出现 */
        i ;
    internalinsert(key, t->p[ i ]);

    if (flag == 0)
        return;
    /* 有新键要插入到当前节点中 */
    if (t->d < 2*m) {/* 当前节点未满 */
        insinnode(t, i); /* 把键值 子树对插入当前节点中 */
        flag = 0; /* 指示上层节点没有需要插入的键值 子树,插入过程结束 */
    }
    else /* 当前节点已满,则分割这个页面并把键值 子树对插入当前节点中 */
        splitnode(t, i); /* 继续指示上层节点把返回的键值 子树插入其中 */
}

/*
* 把一个键和对应的右子树插入一个节点中
*/
void insinnode(btree t, int d)
{
    int i;
    /* 把所有大于要插入的键值的键和对应的右子树右移 */
    for(i = t->d; i > d; i--){
        t->k[ i ] = t->k[i-1];
        t->v[ i ] = t->v[i-1];
        t->p[i 1] = t->p[ i ];
    }
    /* 插入键和右子树 */
    t->k[ i ] = inskey;
    t->p[i 1] = newtree;
    t->v[ i ] = insvalue;
    t->d ;
}
/*
* 前件是要插入一个键和对应的右子树,并且本节点已经满
* 导致分割这个节点,插入键和对应的右子树,
* 并向上层返回一个要插入键和对应的右子树
*/
void splitnode(btree t, int d)
{    
    int i,j;
    btree temp;
    typekey temp_k;
    char *temp_v;
    /* 建立新节点 */
    temp = (btree)malloc(sizeof(node));
    /*
     *   --- -------- ----- ----- -------- -----
     *   | 0 | ...... |  m  | m 1 | ...... |2*m-1|
     *   --- -------- ----- ----- -------- -----
     *   |<-      m 1     ->|<-        m-1     ->|  
     */
    if (d > m) { /* 要插入当前节点的右半部分 */
        /* 把从 2*m-1 到 m 1 的 m-1 个键值 子树对转移到新节点中,
         * 并且为要插入的键值 子树空出位置 */
        for(i=2*m-1,j=m-1; i>=d; i--,j--) {
            temp->k[j] = t->k[ i ];
            temp->v[j] = t->v[ i ];
            temp->p[j 1] = t->p[i 1];
        }
        for(i=d-1,j=d-m-2; j>=0; i--,j--) {
            temp->k[j] = t->k[ i ];
            temp->v[j] = t->v[ i ];
            temp->p[j 1] = t->p[i 1];
        }
        /* 把节点的最右子树转移成新节点的最左子树 */
        temp->p[0] = t->p[m 1];
        /* 在新节点中插入键和右子树 */
        temp->k[d-m-1] = inskey;
        temp->p[d-m] = newtree;
        temp->v[d-m-1] = insvalue;
        /* 设置要插入上层节点的键和值 */
        inskey = t->k[m];
        insvalue = t->v[m];

    }
    else { /* d <= m */
        /* 把从 2*m-1 到 m 的 m 个键值 子树对转移到新节点中 */
        for(i=2*m-1,j=m-1; j>=0; i--,j--) {
            temp->k[j] = t->k[ i ];
            temp->v[j] = t->v[ i ];
            temp->p[j 1] = t->p[i 1];
        }
        if (d == m) /* 要插入当前节点的正中间 */
            /* 把要插入的子树作为新节点的最左子树 */
            temp->p[0] = newtree;
            /* 直接把要插入的键和值返回给上层节点 */
        else { /* (d            /* 把节点当前的最右子树转移成新节点的最左子树 */
            temp->p[0] = t->p[m];
            /* 保存要插入上层节点的键和值 */
            temp_k = t->k[m-1];
            temp_v = t->v[m-1];
            /* 把所有大于要插入的键值的键和对应的右子树右移 */
            for(i=m-1; i>d; i--) {
                t->k[ i ] = t->k[i-1];
                t->v[ i ] = t->v[i-1];
                t->p[i 1] = t->p[ i ];
            }
            /* 在节点中插入键和右子树 */
            t->k[d] = inskey;
            t->p[d 1] = newtree;
            t->v[d] = insvalue;
            /* 设置要插入上层节点的键和值 */
            inskey = temp_k;
            insvalue = temp_v;
        }
    }
    t->d =m;
    temp->d = m;
    newtree = temp;
    node_sum ;
}

btree delete(typekey key, btree t)
{
    level=btree_level;
    internaldelete(key, t);
    if (t->d == 0)
    /* 根节点的子节点合并导致根节点键的数目随之减少,
     * 当根节点中没有键的时候,只有它的最左子树可能非空 */
        t=freeroot(t);
    return t;
}

void internaldelete(typekey key, btree t)
{
    int i,j,m;
    btree l,r;
    int lvl;

    level--;
    if (level < 0) {
        error(0,key); /* 在整个树中未找到要删除的键 */
        flag = 0;
        return;
    }
    for(i=0, j=t->d-1; i t->k[m])?(i=m 1):(j=m));
    if (key == t->k[ i ]) { /* 找到要删除的键 */
        if (t->v[ i ] != null)
            free(t->v[ i ]); /* 释放这个节点包含的值 */
        if (level == 0) { /* 有子树为空则这个键位于叶子节点 */
            delfromnode(t,i);
            btree_count--;
            flag = 1;
            /* 指示上层节点本子树的键数量减少 */
            return;
        } else { /* 这个键位于非叶节点 */
            lvl = level-1;
            /* 找到前驱节点 */
            r = t->p[ i ];
            while (lvl > 0)  {
                r = r->p[r->d];
                lvl--;
            }
            t->k[ i ]=r->k[r->d-1];
            t->v[ i ]=r->v[r->d-1];
            r->v[r->d-1]=null;
            key = r->k[r->d-1];
        }
    }
    else if (key > t->k[ i ]) /* i == t->d-1 时有可能出现 */
        i ;         
    internaldelete(key,t->p[ i ]);
    /* 调整平衡 */
    if (flag == 0)
        return;
    if (t->p[ i ]->d < m) {
        if (i == t->d) /* 在最右子树中发生了删除 */
            i--; /* 调整最右键的左右子树平衡 */
        l = t->p [ i ];
        r = t->p[i 1];
        if (r->d > m)
            moveleftnode(t,i);
        else if(l->d > m)
            moverightnode(t,i);
        else {
            joinnode(t,i);
            /* 继续指示上层节点本子树的键数量减少 */
            return;
        }
        flag = 0;
        /* 指示上层节点本子树的键数量没有减少,删除过程结束 */
    }
}

/*
* 合并一个节点的某个键对应的两个子树
*/
void joinnode(btree t, int d)
{
    btree l,r;
    int i,j;
    l = t->p[d];
    r = t->p[d 1];

    /* 把这个键下移到它的左子树 */
    l->k[l->d] = t->k[d];
    l->v[l->d] = t->v[d];
    /* 把右子树中的所有键值和子树转移到左子树 */
    for (j=r->d-1,i=l->d r->d; j >= 0 ; j--,i--) {
        l->k[ i ] = r->k[j];
        l->v[ i ] = r->v[j];
        l->p[ i ] = r->p[j];
    }
    l->p[l->d r->d 1] = r->p[r->d];
    l->d = r->d 1;
    /* 释放右子树的节点 */
    free(r);
    /* 把这个键右边的键和对应的右子树左移 */
    for (i=d; i < t->d-1; i ) {
        t->k[ i ] = t->k[i 1];
        t->v[ i ] = t->v[i 1];
        t->p[i 1] = t->p[i 2];
    }
    t->d--;
    node_sum--;
}
/*
* 从一个键的右子树向左子树转移一些键,使两个子树平衡
*/
void moveleftnode(btree t, int d)
{
    btree l,r;
    int m; /* 应转移的键的数目 */
    int i,j;
    l = t->p[d];
    r = t->p[d 1];
    m = (r->d - l->d)/2;

    /* 把这个键下移到它的左子树 */
    l->k[l->d] = t->k[d];
    l->v[l->d] = t->v[d];
    /* 把右子树的最左子树转移成左子树的最右子树
     * 从右子树向左子树移动 m-1 个键 子树对 */
    for (j=m-2,i=l->d m-1; j >= 0; j--,i--) {
        l->k[ i ] = r->k[j];
        l->v[ i ] = r->v[j];
        l->p[ i ] = r->p[j];
    }
    l->p[l->d m] = r->p[m-1];
    /* 把右子树的最左键提升到这个键的位置上 */
    t->k[d] = r->k[m-1];
    t->v[d] = r->v[m-1];
    /* 把右子树中的所有键值和子树左移 m 个位置 */
    r->p[0] = r->p[m];
    for (i=0; id-m; i ) {
        r->k[ i ] = r->k[i m];
        r->v[ i ] = r->v[i m];
        r->p[ i ] = r->p[i m];
    }
    r->p[r->d-m] = r->p[r->d];
    l->d =m;
    r->d-=m;
}
/*
* 从一个键的左子树向右子树转移一些键,使两个子树平衡
*/
void moverightnode(btree t, int d)
{
    btree l,r;
    int m; /* 应转移的键的数目 */
    int i,j;
    l = t->p[d];
    r = t->p[d 1];

    m = (l->d - r->d)/2;
    /* 把右子树中的所有键值和子树右移 m 个位置 */
    r->p[r->d m]=r->p[r->d];
    for (i=r->d-1; i>=0; i--) {
        r->k[i m] = r->k[ i ];
        r->v[i m] = r->v[ i ];
        r->p[i m] = r->p[ i ];
    }
    /* 把这个键下移到它的右子树 */
    r->k[m-1] = t->k[d];
    r->v[m-1] = t->v[d];
    /* 把左子树的最右子树转移成右子树的最左子树 */
    r->p[m-1] = l->p[l->d];
    /* 从左子树向右子树移动 m-1 个键 子树对 */
    for (i=l->d-1,j=m-2; j>=0; j--,i--) {
        r->k[j] = l->k[ i ];
        r->v[j] = l->v[ i ];
        r->p[j] = l->p[ i ];
    }
    /* 把左子树的最右键提升到这个键的位置上 */
    t->k[d] = l->k[ i ];
    t->v[d] = l->v[ i ];
    l->d-=m;
    r->d =m;
}
/*
* 把一个键和对应的右子树从一个节点中删除
*/
void delfromnode(btree t, int d)
{
    int i;
    /* 把所有大于要删除的键值的键左移 */
    for(i=d; i < t->d-1; i ) {
        t->k[ i ] = t->k[i 1];
        t->v[ i ] = t->v[i 1];
    }
    t->d--;
}
/*
* 建立有两个子树和一个键的根节点
*/
btree newroot(btree t)
{
    btree temp;
    temp = (btree)malloc(sizeof(node));
    temp->d = 1;
    temp->p[0] = t;
    temp->p[1] = newtree;
    temp->k[0] = inskey;
    temp->v[0] = insvalue;
    btree_level ;
    node_sum ;
    return(temp);
}
/*
* 释放根节点,并返回它的最左子树
*/
btree freeroot(btree t)
{
    btree temp;
    temp = t->p[0];
    free(t);
    btree_level--;
    node_sum--;
    return temp;
}

void error(int f,typekey key)
{
    if (f)
        printf("btrees error: insert %d!\n",key);
    else
        printf("btrees error: delete %d!\n",key);
}

int height(btree t)
{
    return btree_level;
}

int count(btree t)
{
    return btree_count;
}
double payload(btree t)
{
    if (node_sum==0)
        return 1;
    return (double)btree_count/(node_sum*(2*m));
}
btree deltree (btree t)
{    
    level=btree_level;
    btree_level = 0;
    return delall(t);

}
btree delall(btree t)
{
    int i;
    level--;
    if (level >= 0) {
        for (i=0; i < t->d; i )
            if (t->v[ i ] != null)
                free(t->v[ i ]);
        if (level > 0)
            for (i=0; i<= t->d ; i )
                t->p[ i ]=delall(t->p[ i ]);
        free(t);
    }
    return null;
}

/* end of btrees.c */



zhyiwww 2006-07-07 18:24
]]>
经典正则表达式(转载)http://www.blogjava.net/zhyiwww/archive/2006/06/28/55506.htmlzhyiwwwzhyiwwwwed, 28 jun 2006 03:55:00 gmthttp://www.blogjava.net/zhyiwww/archive/2006/06/28/55506.htmlhttp://www.blogjava.net/zhyiwww/comments/55506.htmlhttp://www.blogjava.net/zhyiwww/archive/2006/06/28/55506.html#feedback0http://www.blogjava.net/zhyiwww/comments/commentrss/55506.htmlhttp://www.blogjava.net/zhyiwww/services/trackbacks/55506.html
经典正则表达式
正则表达式用于字符串处理,表单验证等场合,实用高效,但用到时总是不太把握,以致往往要上网查一番。我将一些常用的表达式收藏在这里,作备忘之用。本贴随时会更新。

匹配中文字符的正则表达式: [\u4e00-\u9fa5]

匹配双字节字符(包括汉字在内):[^\x00-\xff]

应用:计算字符串的长度(一个双字节字符长度计2,ascii字符计1)

string.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;}

匹配空行的正则表达式:\n[\s| ]*\r

匹配html标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/

匹配首尾空格的正则表达式:(^\s*)|(\s*$)

应用:javascript中没有像vbscript那样的trim函数,我们就可以利用这个表达式来实现,如下:

string.prototype.trim = function()
{
return this.replace(/(^\s*)|(\s*$)/g, "");
}

利用正则表达式分解和转换ip地址:

下面是利用正则表达式匹配ip地址,并将ip地址转换成对应数值的javascript程序:

function ip2v(ip)
{
re=/(\d )\.(\d )\.(\d )\.(\d )/g //匹配ip地址的正则表达式
if(re.test(ip))
{
return regexp.$1*math.pow(255,3)) regexp.$2*math.pow(255,2)) regexp.$3*255 regexp.$4*1
}
else
{
throw new error("not a valid ip address!")
}
}

不过上面的程序如果不用正则表达式,而直接用split函数来分解可能更简单,程序如下:

var ip="10.100.20.168"
ip=ip.split(".")
alert("ip值是:" (ip[0]*255*255*255 ip[1]*255*255 ip[2]*255 ip[3]*1))

匹配email地址的正则表达式:\w ([- .]\w )*@\w ([-.]\w )*\.\w ([-.]\w )*

匹配网址url的正则表达式:http://([\w-] \.) [\w-] (/[\w- ./?%&=]*)?

利用正则表达式去除字串中重复的字符的算法程序:

var s="abacabefgeeii"
var s1=s.replace(/(.).*\1/g,"$1")
var re=new regexp("[" s1 "]","g")
var s2=s.replace(re,"")
alert(s1 s2) //结果为:abcefgi

我原来在csdn上发贴寻求一个表达式来实现去除重复字符的方法,最终没有找到,这是我能想到的最简单的实现方法。思路是使用后向引用取出包括重复的字符,再以重复的字符建立第二个表达式,取到不重复的字符,两者串连。这个方法对于字符顺序有要求的字符串可能不适用。

得用正则表达式从url地址中提取文件名的javascript程序,如下结果为page1

s="http://www.9499.net/page1.htm"
s=s.replace(/(.*\/){0,}([^\.] ).*/ig,"$2")
alert(s)

利用正则表达式限制网页表单里的文本框输入内容:

用正则表达式限制只能输入中文:onkeyup="value=value.replace(/[^\u4e00-\u9fa5]/g,'')" onbeforepaste="clipboarddata.setdata('text',clipboarddata.getdata('text').replace(/[^\u4e00-\u9fa5]/g,''))"

用正则表达式限制只能输入全角字符: onkeyup="value=value.replace(/[^\uff00-\uffff]/g,'')" onbeforepaste="clipboarddata.setdata('text',clipboarddata.getdata('text').replace(/[^\uff00-\uffff]/g,''))"

用正则表达式限制只能输入数字:onkeyup="value=value.replace(/[^\d]/g,'') "onbeforepaste="clipboarddata.setdata('text',clipboarddata.getdata('text').replace(/[^\d]/g,''))"

用正则表达式限制只能输入数字和英文:onkeyup="value=value.replace(/[\w]/g,'') "onbeforepaste="clipboarddata.setdata('text',clipboarddata.getdata('text').replace(/[^\d]/g,''))"

补充:
^\d $  //匹配非负整数(正整数 0)
^[0-9]*[1-9][0-9]*$  //匹配正整数
^((-\d )|(0 ))$  //匹配非正整数(负整数 0)
^-[0-9]*[1-9][0-9]*$  //匹配负整数
^-?\d $    //匹配整数
^\d (\.\d )?$  //匹配非负浮点数(正浮点数 0)
^(([0-9] \.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9] )|([0-9]*[1-9][0-9]*))$  //匹配正浮点数
^((-\d (\.\d )?)|(0 (\.0 )?))$  //匹配非正浮点数(负浮点数 0)
^(-(([0-9] \.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9] )|([0-9]*[1-9][0-9]*)))$  //匹配负浮点数
^(-?\d )(\.\d )?$  //匹配浮点数
^[a-za-z] $  //匹配由26个英文字母组成的字符串
^[a-z] $  //匹配由26个英文字母的大写组成的字符串
^[a-z] $  //匹配由26个英文字母的小写组成的字符串
^[a-za-z0-9] $  //匹配由数字和26个英文字母组成的字符串
^\w $  //匹配由数字、26个英文字母或者下划线组成的字符串
^[\w-] (\.[\w-] )*@[\w-] (\.[\w-] ) $    //匹配email地址
^[a-za-z] ://匹配(\w (-\w )*)(\.(\w (-\w )*))*(\?\s*)?$  //匹配url


zhyiwww 2006-06-28 11:55
]]>
a tao of regular expressions(转载)http://www.blogjava.net/zhyiwww/archive/2006/06/20/53922.htmlzhyiwwwzhyiwwwtue, 20 jun 2006 03:04:00 gmthttp://www.blogjava.net/zhyiwww/archive/2006/06/20/53922.htmlhttp://www.blogjava.net/zhyiwww/comments/53922.htmlhttp://www.blogjava.net/zhyiwww/archive/2006/06/20/53922.html#feedback1http://www.blogjava.net/zhyiwww/comments/commentrss/53922.htmlhttp://www.blogjava.net/zhyiwww/services/trackbacks/53922.html

blogjava-凯发k8网页登录

steve mansour
sman@scruznet.com
revised: june 5, 1999
(copied by jm /at/ jmason.org from http://www.scruz.net/~sman/regexp.htm, after the original disappeared! )


c o n t e n t s



  

  

  


a regular expression is a formula for matching strings that follow some pattern. many people are afraid to use them because they can look confusing and complicated. unfortunately, nothing in this write up can change that. however, i have found that with a bit of practice, it's pretty easy to write these complicated expressions. plus, once you get the hang of them, you can reduce hours of laborious and error-prone text editing down to minutes or seconds. regular expressions are supported by many text editors, class libraries such as rogue wave's tools.h , scripting tools such as awk, grep, sed, and increasingly in interactive development environments such as microsoft's visual c .

regular expressions usage is explained by examples in the sections that follow. most examples are presented as substitution commands or as file search commands, but they are representative examples and the concepts can be applied in the use of tools such as sed, awk, perl and other programs that support regular expressions. have a look at for examples of regular expression usage in other tools. of vi's substitution command and syntax is provided at the end of this document.

regular expression basics

regular expressions are made up of normal characters and metacharacters. normal characters include upper and lower case letters and digits. the metacharacters have special meanings and are described in detail below.

in the simplest case, a regular expression looks like a standard search string. for example, the regular expression "testing" contains no metacharacters. it will match "testing" and "123testing" but it will not match "testing".

to really make good use of regular expressions it is critical to understand metacharacters. the table below lists metacharacters and a short explanation of their meaning.
 

metacharacter   description


.
matches any single character. for example the regular expression r.t would match the strings rat, rut, r t, but not root
$
matches the end of a line. for example, the regular expression weasel$ would match the end of the string "he's a weasel" but not the string "they are a bunch of weasels.
^
matches the beginning of a line. for example, the regular expression ^when in would match the beginning of the string "when in the course of human events" but would not match "what and when in the"
*
matches zero or more occurences of the character immediately preceding. for example, the regular expression .* means match any number of any characters. 
\
this is the quoting character, use it to treat the following character as an ordinary character. for example, \$ is used to match the dollar sign character ($) rather than the end of a line. similarly, the expression \. is used to match the period character rather than any single character. 
[ ] 
[c1-c2]
[^c1-c2]
matches any one of the characters between the brackets. for example, the regular expression r[aou]t matches rat, rot, and rut, but not ret. ranges of characters can specified by using a hyphen. for example, the regular expression [0-9] means match any digit. multiple ranges can be specified as well. the regular expression [a-za-z] means match any upper or lower case letter. to match any character except those in the range, the complement range, use the caret as the first character after the opening bracket. for example, the expression [^269a-z] will match any characters except 2, 6, 9, and upper case letters. 
\< \>
matches the beginning (\<) or end (\>) or a word. for example, \ matches on "the" in the string "for the wise" but does not match "the" in "otherwise". note: this metacharacter is not supported by all applications.
\( \)
treat the expression between \( and \) as a group. also, saves the characters matched by the expression into temporary holding areas. up to nine pattern matches can be saved in a single regular expression. they can be referenced as \1 through \9.
|
or two conditions together. for example (him|her) matches the line "it belongs to him" and matches the line "it belongs to her" but does not match the line "it belongs to them." note: this metacharacter is not supported by all applications.
matches one or more occurences of the character or regular expression immediately preceding. for example, the regular expression 9 matches 9, 99, 999. note: this metacharacter is not supported by all applications.
?
matches 0 or 1 occurence of the character or regular expression immediately preceding.note: this metacharacter is not supported by all applications.
\{ i \}
\{ i , j \}
match a specific number of instances or instances within a range of the preceding character. for example, the expression a[0-9]\{3\} will match "a" followed by exactly 3 digits. that is, it will match a123 but not a1234. the expression [0-9]\{4,6\} any sequence of 4, 5, or 6 digits. note: this metacharacter is not supported by all applications.


the simplest metacharacter is the dot. it matches any one character (excluding the newline character). consider a file named test.txt consisting of the following lines:

    he is a rat
    he is in a rut
    the food is rotten
    i like root beer
we can use grep to test our regular expressions. grep uses the regular expression we supply and tries to match it to every line of the file. it prints all lines where the regular expression matches at least one sequence of characters on a line. the command
    grep r.t test.txt
searches for the regular expression r.t in each line of test.txt and prints the matching lines. the regular expression r.t matches an r followed by any character followed by a t. it will match rat and rut. it does not match the rot in rotten because regular expressions are case sensitive. to match both the upper and lower the square brackets (character range metacharacters) can be used. the regular expression [rr] matches either ror r. so, to match an upper or lower case r followed by any character followed by the character t the regular expression [rr].t will do the trick.

to match characters at the beginning of a line use the circumflex character (sometimes called a caret). for example, to find the lines containing the word "he" at the beginning of each line in the file test.txt you might first think the use the simple expression he. however, this would match the in the third line. the regular expression ^he only matches the h at the beginning of a line.

sometimes it is easier to indicate something what should not be matched rather than all the cases that should be matched. when the circumflex is the first character between the square brackets it means to match any character which is not in the range. for example, to match he when it is not preceded by t or s, the following regular expression can be used: [^st]he.

several character ranges can be specified between the square brackets. for example, the regular expression [a-za-z] matches any letter in the alphabet, upper or lower case. the regular expression [a-za-z][a-za-z]* matches a letter followed by zero or more letters. we can use the metacharacter to do the same thing. that is, the regular expression [a-za-z] means the same thing as [a-za-z][a-za-z]*. note that the metacharacter is not supported by all programs that have regular expressions. see for more details.

to specify the number of occurrences matched, use the braces (they must be escaped with a backslash). as an example, to match all instances of 100 and 1000 but not 10 or 10000 use the following: 10\{2,3\}. this regular expression matches a the digit 1 followed by either 2 or 3 0's. a useful variation is to omit the second number. for example, the regular expression 0\{3,\} will match 3 or more successive 0's.



zhyiwww 2006-06-20 11:04
]]>
正则表达式之道(转载)http://www.blogjava.net/zhyiwww/archive/2006/06/20/53920.htmlzhyiwwwzhyiwwwtue, 20 jun 2006 02:52:00 gmthttp://www.blogjava.net/zhyiwww/archive/2006/06/20/53920.htmlhttp://www.blogjava.net/zhyiwww/comments/53920.htmlhttp://www.blogjava.net/zhyiwww/archive/2006/06/20/53920.html#feedback0http://www.blogjava.net/zhyiwww/comments/commentrss/53920.htmlhttp://www.blogjava.net/zhyiwww/services/trackbacks/53920.html

原著:steve mansour
sman@scruznet.com
revised: june 5, 1999
(copied by jm /at/ jmason.org from http://www.scruz.net/~sman/regexp.htm, after the original disappeared! )

翻译:neo lee
neo.lee@gmail.com
2004年10月16日


译者按:原文因为年代久远,文中很多链接早已过期(主要是关于vi、sed等工具的介绍和手册),本译文中已将此类链接删除,如需检查这些链接可以查看上面链接的原文。除此之外基本照原文直译,括号中有“译者按”的部分是译者补充的说明。如有内容方面的问题请直接和steve mansor联系,当然,如果你只写中文,也可以和我联系。




  
  
  


一个正则表达式,就是用某种模式去匹配一类字符串的一个公式。很多人因为它们看上去比较古怪而且复杂所以不敢去使用——很不幸,这篇文章也不能够改变这一点,不过,经过一点点练习之后我就开始觉得这些复杂的表达式其实写起来还是相当简单的,而且,一旦你弄懂它们,你就能把数小时辛苦而且易错的文本处理工作压缩在几分钟(甚至几秒钟)内完成。正则表达式被各种文本编辑软件、类库(例如rogue wave的tools.h )、脚本工具(像awk/grep/sed)广泛的支持,而且像microsoft的visual c 这种交互式ide也开始支持它了。

我们将在如下的章节中利用一些例子来解释正则表达式的用法,绝大部分的例子是基于vi中的文本替换命令和grep文件搜索命令来书写的,不过它们都是比较典型的例子,其中的概念可以在sed、awk、perl和其他支持正则表达式的编程语言中使用。你可以看看这一节,其中有一些在别的工具中使用正则表达式的例子。还有一个关于vi中文本替换命令(s)的附在文后供参考。

正则表达式基础

正则表达式由一些普通字符和一些元字符(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义,我们下面会给予解释。

在最简单的情况下,一个正则表达式看上去就是一个普通的查找串。例如,正则表达式"testing"中没有包含任何元字符,,它可以匹配"testing"和"123testing"等字符串,但是不能匹配"testing"。

要想真正的用好正则表达式,正确的理解元字符是最重要的事情。下表列出了所有的元字符和对它们的一个简短的描述。

元字符 描述


.
匹配任何单个字符。例如正则表达式r.t匹配这些字符串:ratrutr t,但是不匹配root。 
$
匹配行结束符。例如正则表达式weasel$ 能够匹配字符串"he's a weasel"的末尾,但是不能匹配字符串"they are a bunch of weasels."。 
^
匹配一行的开始。例如正则表达式^when in能够匹配字符串"when in the course of human events"的开始,但是不能匹配"what and when in the"。
*
匹配0或多个正好在它之前的那个字符。例如正则表达式.*意味着能够匹配任意数量的任何字符。
\
这是引用府,用来将这里列出的这些元字符当作普通的字符来进行匹配。例如正则表达式\$被用来匹配美元符号,而不是行尾,类似的,正则表达式\.用来匹配点字符,而不是任何字符的通配符。
[ ] 
[c1-c2]
[^c1-c2]
匹配括号中的任何一个字符。例如正则表达式r[aou]t匹配ratrotrut,但是不匹配ret。可以在括号中使用连字符-来指定字符的区间,例如正则表达式[0-9]可以匹配任何数字字符;还可以制定多个区间,例如正则表达式[a-za-z]可以匹配任何大小写字母。另一个重要的用法是“排除”,要想匹配除了指定区间之外的字符——也就是所谓的补集——在左边的括号和第一个字符之间使用^字符,例如正则表达式[^269a-z] 将匹配除了2、6、9和所有大写字母之外的任何字符。
\< \>
匹配词(word)的开始(\<)和结束(\>)。例如正则表达式\能够匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:这个元字符不是所有的软件都支持的。
\( \)
将 \( 和 \) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1\9 的符号来引用。
|
将两个匹配条件进行逻辑“或”(or)运算。例如正则表达式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。
匹配1或多个正好在它之前的那个字符。例如正则表达式9 匹配9、99、999等。注意:这个元字符不是所有的软件都支持的。
?
匹配0或1个正好在它之前的那个字符。注意:这个元字符不是所有的软件都支持的。
\{i\}
\{i,j\}
匹配指定数目的字符,这些字符是在它之前的表达式定义的。例如正则表达式a[0-9]\{3\} 能够匹配字符"a"后面跟着正好3个数字字符的串,例如a123、a348等,但是不匹配a1234。而正则表达式[0-9]\{4,6\} 匹配连续的任意4个、5个或者6个数字字符。注意:这个元字符不是所有的软件都支持的。

最简单的元字符是点,它能够匹配任何单个字符(注意包括新行符)。假定有个文件test.txt包含以下几行内容:

    he is a rat
    he is in a rut
    the food is rotten
    i like root beer
我们可以使用grep命令来测试我们的正则表达式,grep命令使用正则表达式去尝试匹配指定文件的每一行,并将至少有一处匹配表达式的所有行显示出来。命令
    grep r.t test.txt
在test.txt文件中的每一行中搜索正则表达式r.t,并打印输出匹配的行。正则表达式r.t匹配一个r接着任何一个字符再接着一个t。所以它将匹配文件中的ratrut,而不能匹配rotten中的rot,因为正则表达式是大小写敏感的。要想同时匹配大写和小写字母,应该使用字符区间元字符(方括号)。正则表达式[rr]能够同时匹配rr。所以,要想匹配一个大写或者小写的r接着任何一个字符再接着一个t就要使用这个表达式:[rr].t

要想匹配行首的字符要使用抑扬字符(^)——又是也被叫做插入符。例如,想找到text.txt中行首"he"打头的行,你可能会先用简单表达式he,但是这会匹配第三行的the,所以要使用正则表达式^he,它只匹配在行首出现的h

有时候指定“除了×××都匹配”会比较容易达到目的,当抑扬字符(^)出现在方括号中是,它表示“排除”,例如要匹配he ,但是排除前面是t or s的情性(也就是theshe),可以使用:[^st]he

可以使用方括号来指定多个字符区间。例如正则表达式[a-za-z]匹配任何字母,包括大写和小写的;正则表达式[a-za-z][a-za-z]* 匹配一个字母后面接着0或者多个字母(大写或者小写)。当然我们也可以用元字符 做到同样的事情,也就是:[a-za-z] ,和[a-za-z][a-za-z]*完全等价。但是要注意元字符 并不是所有支持正则表达式的程序都支持的。关于这一点可以参考后面的。

要指定特定数量的匹配,要使用大括号(注意必须使用反斜杠来转义)。想匹配所有1001000的实例而排除1010000,可以使用:10\{2,3\},这个正则表达式匹配数字1后面跟着2或者3个0的模式。在这个元字符的使用中一个有用的变化是忽略第二个数字,例如正则表达式0\{3,\} 将匹配至少3个连续的0。

简单的例子

这里有一些有代表性的、比较简单的例子。

vi 命令作用


:%s/ */ /g把一个或者多个空格替换为一个空格。
:%s/ *$//去掉行尾的所有空格。
:%s/^/ /在每一行头上加入一个空格。
:%s/^[0-9][0-9]* //去掉行首的所有数字字符。
:%s/b[aeio]g/bug/g将所有的bagbegbigbog改为bug。 
:%s/t\([aou]\)g/h\1t/g将所有tagtogtug分别改为hathothug(注意用group的用法和使用\1引用前面被匹配的字符)。

中级的例子(神奇的咒语)

例1

将所有方法foo(a,b,c)的实例改为foo(b,a,c)。这里a、b和c可以是任何提供给方法foo()的参数。也就是说我们要实现这样的转换:

之前 之后
foo(10,7,2)foo(7,10,2)
foo(x 13,y-2,10)foo(y-2,x 13,10)
foo( bar(8), x y z, 5)foo( x y z, bar(8), 5)

下面这条替换命令能够实现这一魔法:

    :%s/foo(\([^,]*\),\([^,]*\),\([^)]*\))/foo(\2,\1,\3)/g

现在让我们把它打散来加以分析。写出这个表达式的基本思路是找出foo()和它的括号中的三个参数的位置。第一个参数是用这个表达式来识别的::\([^,]*\),我们可以从里向外来分析它: 

[^,] 除了逗号之外的任何字符
[^,]*0或者多个非逗号字符
\([^,]*\)将这些非逗号字符标记为\1,这样可以在之后的替换模式表达式中引用它
\([^,]*\),我们必须找到0或者多个非逗号字符后面跟着一个逗号,并且非逗号字符那部分要标记出来以备后用。

现在正是指出一个使用正则表达式常见错误的最佳时机。为什么我们要使用[^,]*这样的一个表达式,而不是更加简单直接的写法,例如:.*,来匹配第一个参数呢?设想我们使用模式.*来匹配字符串"10,7,2",它应该匹配"10,"还是"10,7,"?为了解决这个两义性(ambiguity),正则表达式规定一律按照最长的串来,在上面的例子中就是"10,7,",显然这样就找出了两个参数而不是我们期望的一个。所以,我们要使用[^,]*来强制取出第一个逗号之前的部分。

这个表达式我们已经分析到了:foo(\([^,]*\),这一段可以简单的翻译为“当你找到foo(就把其后直到第一个逗号之前的部分标记为\1”。然后我们使用同样的办法标记第二个参数为\2。对第三个参数的标记方法也是一样,只是我们要搜索所有的字符直到右括号。我们并没有必要去搜索第三个参数,因为我们不需要调整它的位置,但是这样的模式能够保证我们只去替换那些有三个参数的foo()方法调用,在foo()是一个重载(overoading)方法时这种明确的模式往往是比较保险的。然后,在替换部分,我们找到foo()的对应实例,然后利用标记好的部分进行替换,是的第一和第二个参数交换位置。

例2

假设有一个csv(comma separated value)文件,里面有一些我们需要的信息,但是格式却有问题,目前数据的列顺序是:姓名,公司名,州名缩写,邮政编码,现在我们希望讲这些数据重新组织,以便在我们的某个软件中使用,需要的格式为:姓名,州名缩写-邮政编码,公司名。也就是说,我们要调整列顺序,还要合并两个列来构成一个新列。另外,我们的软件不能接受逗号前后面有任何空格(包括空格和制表符)所以我们还必须要去掉逗号前后的所有空格。

这里有几行我们现在的数据:

    bill jones,     hi-tek corporation ,  ca, 95011
    sharon lee smith,  design works incorporated,  ca, 95012
    b. amos   ,  hill street cafe,  ca, 95013
    alexander weatherworth,  the crafts store,  ca, 95014
    ...
我们希望把它变成这个样子:
    bill jones,ca 95011,hi-tek corporation
    sharon lee smith,ca 95012,design works incorporated
    b. amos,ca 95013,hill street cafe
    alexander weatherworth,ca 95014,the crafts store
    ...
我们将用两个正则表达式来解决这个问题。第一个移动列和合并列,第二个用来去掉空格。

下面就是第一个替换命令:

    :%s/\([^,]*\),\([^,]*\),\([^,]*\),\(.*\)/\1,\3 \4,\2/
这里的方法跟例1基本一样,第一个列(姓名)用这个表达式来匹配:\([^,]*\),即第一个逗号之前的所有字符,而姓名内容被用\1标记下来。公司名和州名缩写字段用同样的方法标记为\2\3,而最后一个字段用\(.*\)来匹配("匹配所有字符直到行末")。替换部分则引用上面标记的那些内容来进行构造。

下面这个替换命令则用来去除空格:

    :%s/[ \t]*,[ \t]*/,/g
我们还是分解来看:[ \t]匹配空格/制表符,[ \t]* 匹配0或多个空格/制表符,[ \t]*,匹配0或多个空格/制表符后面再加一个逗号,最后,[ \t]*,[ \t]*匹配0或多个空格/制表符接着一个逗号再接着0或多个空格/制表符。在替换部分,我们简单的我们找到的所有东西替换成一个逗号。这里我们使用了结尾的可选的g参数,这表示在每行中对所有匹配的串执行替换(而不是缺省的只替换第一个匹配串)。

例3

假设有一个多字符的片断重复出现,例如:
billy tried really hard
sally tried really really hard
timmy tried really really really hard
johnny tried really really really really hard
而你想把"really"、"really really",以及任意数量连续出现的"really"字符串换成一个简单的"very"(simple is good!),那么以下命令:
:%s/\(really \)\(really \)*/very /
就会把上述的文本变成:
billy tried very hard
sally tried very hard
timmy tried very hard
johnny tried very hard
表达式\(really \)*匹配0或多个连续的"really "(注意结尾有个空格),而\(really \)\(really \)* 匹配1个或多个连续的"really "实例。

困难的例子(不可思议的象形文字)

coming soon.
ok,你已经准备使用re(regular expressions,正则表达式),但是你并准备使用vi。所以,在这里我们给出一些在其他工具中使用re的例子。另外,我还会总结一下你在不同程序之间使用re可能发现的区别。

当然,你也可以在visual c 编辑器中使用re。选择edit->replace,然后选择"regular expression"选择框,find what输入框对应上面介绍的vi命令:%s/pat1/pat2/g中的pat1部分,而replace输入框对应pat2部分。但是,为了得到vi的执行范围和g选项,你要使用replace all或者适当的手工find next and replace(译者按:知道为啥有人骂微软弱智了吧,虽然vc中可以选中一个范围的文本,然后在其中执行替换,但是总之不够vi那么灵活和典雅)。

sed

sed是stream editor的缩写,是unix下常用的基于文件和管道的编辑工具,可以在手册中得到关于sed的详细信息。

这里是一些有趣的sed脚本,假定我们正在处理一个叫做price.txt的文件。注意这些编辑并不会改变源文件,sed只是处理源文件的每一行并把结果显示在标准输出中(当然很容易使用重定向来定制):

sed脚本 描述


sed 's/^$/d' price.txt删除所有空行
sed 's/^[ \t]*$/d' price.txt删除所有只包含空格或者制表符的行
sed 's/"//g' price.txt删除所有引号

awk

awk是一种编程语言,可以用来对文本数据进行复杂的分析和处理。可以在手册中得到关于awk的详细信息。这个古怪的名字是它作者们的姓的缩写(aho,weinberger和kernighan)。

在aho,weinberger和kernighan的书the awk programming language中有很多很好的awk的例子,请不要让下面这些微不足道的脚本例子限制你对awk强大能力的理解。我们同样假定我们针对price.txt文件进行处理,跟sed一样,awk也只是把结果显示在终端上。 

awk脚本 描述


awk '$0 !~ /^$/' price.txt删除所有空行
awk 'nf > 0' price.txtawk中一个更好的删除所有行的办法
awk '$2 ~ /^[jt]/ {print $3}' price.txt打印所有第二个字段是'j'或者't'打头的行中的第三个字段
awk '$2 !~ /[mm]isc/ {print $3 $4}' price.txt针对所有第二个字段不包含'misc'或者'misc'的行,打印第3和第4列的和(假定为数字)
awk '$3 !~ /^[0-9] \.[0-9]*$/ {print $0}' price.txt打印所有第三个字段不是数字的行,这里数字是指d.d或者d这样的形式,其中d是0到9的任何数字
awk '$2 ~ /john|fred/ {print $0}' price.txt如果第二个字段包含'john'或者'fred'则打印整行

grep

grep是一个用来在一个或者多个文件或者输入流中使用re进行查找的程序。它的name编程语言可以用来针对文件和管道进行处理。可以在手册中得到关于grep的完整信息。这个同样古怪的名字来源于vi的一个命令,g/re/p,意思是global regular expression print。

下面的例子中我们假定在文件phone.txt中包含以下的文本,——其格式是姓加一个逗号,然后是名,然后是一个制表符,然后是电话号码:

    francis, john           5-3871
    wong, fred              4-4123
    jones, thomas           1-4122
    salazar, richard        5-2522

grep命令 描述


grep '\t5-...1' phone.txt把所有电话号码以5开头以1结束的行打印出来,注意制表符是用\t表示的
grep '^s[^ ]* r' phone.txt打印所有姓以s打头和名以r打头的行
grep '^[jw]' phone.txt打印所有姓开头是j或者w的行
grep ', ....\t' phone.txt打印所有姓是4个字符的行,注意制表符是用\t表示的
grep -v '^[jw]' phone.txt打印所有不以j或者w开头的行
grep '^[m-z]' phone.txt打印所有姓的开头是m到z之间任一字符的行
grep '^[m-z].*[12]' phone.txt打印所有姓的开头是m到z之间任一字符,并且点号号码结尾是1或者2的行

egrep

egrep是grep的一个扩展版本,它在它的正则表达式中支持更多的元字符。下面的例子中我们假定在文件phone.txt中包含以下的文本,——其格式是姓加一个逗号,然后是名,然后是一个制表符,然后是电话号码:
    francis, john           5-3871
    wong, fred              4-4123
    jones, thomas           1-4122
    salazar, richard        5-2522
egrep command description


egrep '(john|fred)' phone.txt打印所有包含名字john或者fred的行
egrep 'john|22$|^w' phone.txt打印所有包含john 或者以22结束或者以w的行
egrep 'net(work)?s' report.txt从report.txt中找到所有包含networks或者nets的行


命令或环境.[ ]^$\( \)\{ \}? |( )
vi x  x  x  x  x      
visual c  x  x  x  x  x      
awk x  x  x  x    x  x  x  x 
sed x  x  x  x  x  x     
tcl x  x  x  x  x   x  x  x  x 
ex x  x  x  x  x  x     
grep x  x  x  x  x  x     
egrep x  x x  x  x   x  x  x  x 
fgrep x  x  x  x  x      
perl x x x x x  x x x x

 


vi的替换命令:
    :ranges/pat1/pat2/g
其中
    : 这是vi的命令执行界面。
    range 是命令执行范围的指定,可以使用百分号(%)表示所有行,使用点(.)表示当前行,使用美元符号($)表示最后一行。你还可以使用行号,例如10,20表示第10到20行,.,$表示当前行到最后一行,. 2,$-5表示当前行后两行直到全文的倒数第五行,等等。

    s 表示其后是一个替换命令。

    pat1 这是要查找的一个正则表达式,这篇文章中有一大堆例子。

    pat2 这是希望把匹配串变成的模式的正则表达式,这篇文章中有一大堆例子。

    g 可选标志,带这个标志表示替换将针对行中每个匹配的串进行,否则则只替换行中第一个匹配串。

网上有很多vi的在线手册,你可以访问他们以获得更加完整的信息。

zhyiwww 2006-06-20 10:52
]]>
网站地图