常用的正则表达式

常用正则表达式

正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常用的表达式收集于此,以备不时之需。

用户名:/^[a-z0-9_-]{3,16}$/

密码:/^[a-z0-9_-]{6,18}$/

十六进制值:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/

电子邮箱:/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/

URL:/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/

IP 地址:/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/或者^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$

HTML 标签:/^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/

Unicode编码中的汉字范围:/^[u4e00-u9fa5],{0,}$/

hostname:

^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$

Read more

undefined symbols “typeinfo” for XXX calss

问题描述

在使用虚基类的时候,编译遇到了如下错误:

Undefined symbols for architecture x86_64:
  "typeinfo for HandlerBase", referenced from:
      typeinfo for DNSResolveHandler in test-dns-b857ca.o
      typeinfo for DNSResolver in asyncdns-061190.o
  "vtable for HandlerBase", referenced from:
      HandlerBase::HandlerBase() in test-dns-b857ca.o
      HandlerBase::HandlerBase() in asyncdns-061190.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Read more

this指针转化为智能指针的正确方式

在C++类内部的非静态成员函数内部,是不能将this指针强制转化成shared_ptr,这样的行为是非常危险的,因为this指针是普通指针,而将普通指针强制转化成智能指针是非常非常非常危险的,有可能导致内存被意外释放。

在class内部,获得this指针的shared_ptr,需要class继承std::enable_shared_from_this,示例代码如下: Read more

正则表达式零宽断言详解

基本概念

零宽断言正如它的名字一样,是一种零宽度的匹配,它匹配到的内容不会保存到匹配结果中去,最终匹配结果只是一个位置而已。
作用是给指定位置添加一个限定条件,用来规定此位置之前或者之后的字符必须满足限定条件才能使正则中的字表达式匹配成功。
注意:这里所说的子表达式并非只有用小括号括起来的表达式,而是正则表达式中的任意匹配单元。
javascript只支持零宽先行断言,而零宽先行断言又可以分为正向零宽先行断言,和负向零宽先行断言。 Read more

C++经典面试题(最全,面中率最高)

1.new、delete、malloc、free关系

delete会调用对象的析构函数,和new对应free只会释放内存,new调用构造函数。malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。 Read more

C++知识点

操作符重载

赋值运算符重载

  • 返回值的类型为引用,并在函数结束前返回实例自身的引用(*this)。但是返回引用的目的不是为了允许连续赋值,因为返回实例本身也可以连续赋值。返回引用是为了提高效率。如果返回实例,赋值运算符重载函数会自动调用拷贝构造函数创建一个临时对象,并在连续赋值完毕后自动调用析构函数,增加了程序开销。另外,如果没有自己定义性能良好的拷贝构造函数,会调用默认拷贝构造函数。而默认拷贝构造函数的是浅拷贝,当实例中有指针时,无法正确拷贝一个实例。需要注意的是,当返回值的类型为引用时,赋值操作符号返回一个reference(引用)指向操作符号的左侧实参(而事实上重载运算符的左侧实参就是调用对象本身)。
  • 传入的参数应该是常量引用。引用的目的是为了不调用拷贝构造函数,常量的目的是在赋值操作符重载函数中不会修改传入的参数。
  • 是否释放已有的内存。如果我们忘记在分配新内存之前释放自身已有的空间,则程序将出现内存泄漏。
  • 判断传入的参数是不是当前的实例(*this)。如果事先不判断就赋值,那么在释放自身内存后,就无法找到需要赋值的内容了。

 

 

Solution2 for GSH

#include <iostream>
#include <vector>
#include <string>
#include <climits>

int main() {

    int n;
    int temp;
    std::cin >> n;
    std::vector<int> numbers(n, 0);
    std::vector<int> dp(n, 0);
    for(int i = 0; i < n; ++i)
    {
        std::cin >> temp;
        numbers[i] = temp;
        dp[i] = i;
    }
    for(int i = 2; i < n; ++i)
    {
        for(int j = 0; j < i; ++j)
        {
            if(numbers[j] >= i - j)
            {
                dp[i] = std::min(dp[j]+1, dp[i]);
            }
        }
    }
    std::cout << dp[n-1] << std::endl;

    return 0;
}

 

Solution for GSH

#include <iostream>
#include <vector>
#include <string>

int main() {
    std::string inStr;
    int num[255] = {0};
    std::vector<int> vecPair(255, 0);
    std::cin >> inStr; // read input stream
    for(auto iter = inStr.begin(); iter != inStr.end(); ++iter)
    {
        ++vecPair[*iter];
    }
    // output
    int outputNum = 0;
    while(outputNum < inStr.size())
    {
        for(int i = 48; i <= 57; ++i)
        {
            if(vecPair[i] != 0)
            {
                --vecPair[i];
                ++outputNum;
                std::cout << static_cast<char>(i);
            }
        }
        for(int i = 65; i <= 90; ++i)
        {
            if(vecPair[i] != 0)
            {
                --vecPair[i];
                ++outputNum;
                std::cout << static_cast<char>(i);
            }
        }
        for(int i = 97; i <= 122; ++i)
        {
            if(vecPair[i] != 0)
            {
                --vecPair[i];
                ++outputNum;
                std::cout << static_cast<char>(i);
            }
        }
    }
    std::cout << std::endl;

    return 0;
}

 

decltype和auto的区别

注意:引用类型的变量必须初始化,本文在个别示例代码中没有做详细说明,请注意。

auto

编程时候常常需要把表达式的值付给变量,需要在声明变量的时候清楚的知道变量是什么类型。然而做到这一点并非那么容易(特别是模板中),有时候根本做不到。为了解决这个问题,C++11新标准就引入了auto类型说明符,利用auto关键字,编译器会根据所赋值的类型推断变量的类型,因此,使用auto声明的变量必须初始化Read more

请说出static和const关键字尽可能多的作用

static关键字至少有下列n个作用

  • 函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
  • 在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其他函数访问;
  • 在模块内的static函数只能被这一模块内的其他函数调用,这个函数的使用范围被限制在声明它的模块内;
  • 在类中的static成员变量属于整个类所有,对类的所有对象只有一份拷贝;
  • 在类中的static成员函数属于整个类所有,这个函数不接受this指针,因而只能访问类的static成员变量。

Read more