发布新日志

  • 周末浏览智联

    2010-07-11 12:21:31

    最近在公司,总是加班,加班,加班。。。周一到周五加到9点,10点,周末要求周六还要来加班。没有加班费。于是想换个公司。今天在智联上浏览。看了一下自动化测试的职位,觉得里面的要求自己又不太符合。Unix/Linux不会,没事多学学。都说是8小时工作制,可在中国,有多少公司是12小时工作制甚至更长时间。有多少公司不遵守劳动法。
    每天在这样加下去,真的很累。寻找新的出路。。。提高自己,等待新的机会。。。
  • 阳光VS阴暗

    2010-07-05 21:57:39

    看了倪玉兰的故事,觉得社会好黑暗。如果总这样想,活的很累。河滩快乐?
    如果忽视这些,只强迫自己去看阳光的一面。又觉得不真实。
    自己还是一颗做自己的心,不去管太多。
     
  • powershell 学习

    2010-07-04 15:19:57

    Be calm for some days. Then update resume.
     
    领导的话,别人说过像“艹你妈”。永远不可能实现。一些人被盘算了,一小部分人仍然过着舒服的日子。有个同事,真的替她感到不平。希望我们在经历这次的盘算后,能不再被盘算。也过上舒适的生活。
     
    学习Powershell.
  • 拒绝offer

    2009-12-11 21:02:42

    这些天真是吃啥啥不香,睡觉也没滋味。

    做外包测试工作,想跳槽,接收了两个offer, 有一个确认了,但现在想拒绝,本来以为诚心道歉,解释清楚原因就可以了。因为另外一个项目比较稳定,而且待遇也好一点。可谁知道拒绝后竟然还非要我去面谈。offer不是这样拒绝吗?我真的已经感到很自责了,也很抱歉,去面谈真的有点怕耶! 大家有这样的经历吗?

    第一次跳槽,就出这么多状况。希望自己可以有自己的主见,下定决心不动摇。越动摇越麻烦,事情越糟糕。

  • 跳槽的感想

    2009-12-07 15:46:37

    跳槽了,感觉出强大的风险与不安。以前没跳过槽,真的不能体会这种感觉。

    跳槽终于结束了,下周要上班了,期间面了10来次,四家公司,还是选最初的那个。有的时候很不爽啊,经常会被”鄙视“。

    有的公司,和个别HR都是大骗子!自己一定要详细问清楚情况,要不白白面试了好几次。可能我太笨啊。 大家要小心就是了。

    再跳就跳不动了。争取跳出外包!

     

  • (转载)string operation

    2009-12-01 16:55:33

    C# String操作
    2007年04月09日 星期一 下午 03:52

    字符串的使用 一、标记
    标记(tokenizing)是从文本中提取具体内容的过程。
    下面的代码从句子中提取单词,并把它们输出到控制台。
    class mytokenizing
    {
        static void Main(string[ ] args)
        {
           string mystring="I like this food,are you?";
           char[] separators={' ',',','?',':','!'};
           int startpos=0;
           int endpos=0;
           do
           {
              endpos=mystring.IndexOfAny(separators,startpos);
              if ( endpos==-1 ) endpos=mystring.Length;
              if ( endpos!=startpos )
                   Console.WriteLine(mystring.Substring( startpos,(endpos-startpos)));
              startpos=(endpos+1);
           }while(startpos<mystring.Length);
        }
    }
    I     <== 输出
    like
    this
    food
    are
    you

    二、颠倒字符串次序
    class myreverse
    {
        static void Main(string [] args)
        {
           string mystring="你们好";
           char[] mychars=mystring.ToCharArray( );
           Array.Reverse(mychars);
           Console.WriteLine(mystring);
           Console.WriteLine(mychars);
        }
    }
    任何继承于Array的类都能利用Reverse( )方法为数组中的元素重新排序。

    三、字符串的插入、删除和替换
    示例文件test.txt为字符串的来源。下面代码以Unicode格式读取文本。确保文件保存为读取时的格式。例如记事本允许将代码保存为Unicode:
    aaaaaaaa,bbbbbbbb,cccccc
    dddddddd,eeeeeeee,ffffff
    gggggggg,hhhhhhhh,iiiiii
    jjjjjjjj,kkkkkkkk,llllll

    下面代码加载数据并处理数据的测试工具。测试结果发送给控制台。
    class myprocessfile
    {
        static void Main(string [] args)
        {
           const string myName="test.txt";
           Stream readLine;
           TextWirter writeLine;
           StringBuilder sb;
           readLine=File.OpenRead(myName);
           WriteLine=Console.Out;
           StreamReader readLineSReader=new StreamReader(readLine,Encoding.Unicode);
           readLineSReader.BaseStream.Seek(0,SeekOrigin.Begin);
           while(readLineSReader.Peek()>-1)
           {
              sb=new StringBuilder(readLineSReader.ReadLine());
              //插入字符串操作语句如:sb.Append(",123");
              Console.WriteLine(sb.ToString());
           }
        }
    }

    在结尾添加一列内容:
    //displays aaaaaaaa,bbbbbbbb,cccccc,xxxxx
    //......
    sb.Append(",xxxxx");

    第一列可以使用下面的代码删除:
    //displays bbbbbbbb,cccccc
    //......
    sb.Remove(0,sb.ToString().IndexOf(',')+1);

    替换分隔符:
    //aaaaaaaa+bbbbbbbb+cccccc
    sb.Replace(',','+');

    添加行号(lineNumber已经在前面某处声明过为前提):
    sb.Insert(0,lineNumber.ToString("000 "));
    lineNumber++;

    //displays
    //000 aaaaaaaa,bbbbbbbb,cccccc
    //001 dddddddd,eeeeeeee,ffffff
    //002 gggggggg,hhhhhhhh,iiiiii
    //003 jjjjjjjj,kkkkkkkk,llllll

    字符串操作


    1、从字符串中提取子串
    StringBuilder 类没有支持子串的方法,因此必须用String类来提取。
    string mystring="My name is ynn.";
    //Displays "name is ynn."
    Console.WriteLine(mystring.Substring( 3 ));
    //Displays "ynn"
    Console.WriteLine(mystring.Substring( 11,3 ));

    2、比较字符串
    String 类有四种方法:Compare( )、CompareTo( )、CompareOrdinal( )、Equals( )。
    Compare( )方法是CompareTo( )方法的静态版本。只要使用“=”运算符,就会调用Equals( )方法,的以Equals( )方法与“=”是等价的。CompareOrdinal( )方法对两个字符串比较不考本地语言与文件。
    示例:
    int result;
    bool bresult;
    s1="aaaa";
    s2="bbbb";
    //Compare( )method
    //result值为“0”表示等,小于零表示 s1 < s2,大于零表示 s1 > s2
    result=String.Compare(s1,s2);
    result=s1.CompareTo( s2 );
    result=String.CompareOrdinal(s1,s2);
    bresult=s1.Equals( s2 );
    bresult=String.Equals( s1,s2 );
    一个例外情况是,两个字符串都是内置的,并相等,静态方法要快得多。

    3、字符串格式化

    3.1 格式化数字
    格式字符     说明和关联属性


    c、C        货币格式。
    d、D        十进制格式。
    e、E        科学计数(指数)格式。
    f、F        固定点格式。
    g、G        常规格式。
    n、N        数字格式。
    r、R        往返格式,确保将已转换成字符串的数字转换回数字时具有与原数字相同的值。
    x、X        十六进制格式。


    double val=Math.PI;
    Console.WriteLine(val.ToString( )); //displays 3.14159265358979
    Console.WriteLine(val.ToString("E"));//displays 3.141593E+000
    Console.WriteLine(val.ToString("F3");//displays 3.142
    int val=65535;
    Console.WriteLine(val.ToString("x")); //displays ffff
    Console.WriteLine(val.ToString("X")); //displays FFFF
    Single val=0.123F;
    Console.WriteLine(val.ToString("p")); //displays 12.30 %
    Console.WriteLine(val.ToString("p1")); //displays 12.3 %
    默认格式化会在数字和百分号之间放入一个空格。定制方法如下:
    其中NumberFormatInfo类是System.Globalization命名空间的一个成员,因此该命名空间必须导入到程序中。
    Single val=0.123F;
    object myobj=NumberFormatInfo.CurrentInfo.Clone( ) as NumberFormatInfo;
    NumberFormatInfo myformat=myobj as NumberFormatInfo;
    myformat.PercentPositivePattern=1;
    Console.WriteLine(val.ToString("p",myformat)); //displays 12.30%;
    Console.WriteLine(val.ToString("p1",myformat)); //displays 12.3%;
    格式化具有很大的灵活性。下面的例子演示一个没有意义的货币结构:
    double val=1234567.89;
    int [] groupsize={2,1,3};
    object myobj=NumberFormatInfo.CurrentInfo.Clone( );
    NumberFormatInfo mycurrency=myobj as NumberFormatInfo;
    mycurrency.CurrencySymbol="#"; //符号
    mycurrency.CurrencyDecimalSeparator=":"; //小数点
    mycurrency.CurrencyGroupSeparator="_"; //分隔符
    mycurrency.CurrencyGroupSizes=groupsize;
    // 输出 #1_234_5_67:89
    Console.WriteLine(val.ToString("C",mycurrency));

    3.2 格式化日期
    输出形式取决于用户计算机的文化设置。
    using System;
    using System.Globalization;
    public class MainClass
    {
    public static void Main(string[] args)
    {
             DateTime dt = DateTime.Now;
             String[] format = {"d","D","f","F","g","G","m","r","s","t", "T","u", "U","y","dddd, MMMM dd yyyy","ddd, MMM d \"'\"yy","dddd, MMMM dd","M/yy","dd-MM-yy",};
             String date;
           for (int i = 0; i < format.Length; i++)
           {
              date = dt.ToString(format[i], DateTimeFormatInfo.InvariantInfo);
              Console.WriteLine(String.Concat(format[i], " :" , date));
           }
          }
    }
    d :07/11/2004     <=======输出
    D :Sunday, 11 July 2004
    f :Sunday, 11 July 2004 10:52
    F :Sunday, 11 July 2004 10:52:36
    g :07/11/2004 10:52
    G :07/11/2004 10:52:36
    m :July 11
    r :Sun, 11 Jul 2004 10:52:36 GMT
    s :2004-07-11T10:52:36
    t :10:52
    T :10:52:36
    u :2004-07-11 10:52:36Z
    U :Sunday, 11 July 2004 02:52:36
    y :2004 July
    dddd, MMMM dd yyyy :Sunday, July 11 2004
    ddd, MMM d "'"yy :Sun, Jul 11 '04
    dddd, MMMM dd :Sunday, July 11
    M/yy :7/04
    dd-MM-yy :11-07-04

    3.3 格式化枚举
    enum classmen
    {
    ynn=1,
    yly=2,
    css=3,
    C++=4
    }
    获取枚举字符串信息如下:
    classmen myclassmen=classmen.yly;
    Console.WriteLine(myclassmen.ToString( ));    //displays yly
    Console.WriteLine(myclassmen.ToString("d")); //displays 2
    从系统枚举中获取文本人信息如下:
    DayOfWeek day=DayOfWeek.Friday;
    //displays "Day is Friday"
    Console.WriteLine(String.Format("Day is {0:G}",day));
    格式化字符串“ G ”把枚举显示为一个字符串。

    StringBuilder 类学习笔记

      String类的不可改变性使它更像一个值类型而不是一个引用类型。其副作用是每次执行字符操作时,都会创建一个新的String对象。StringBuilder 类解决了对字符串进行重复修改的过程中创建大量对象的问题。

    StringBuilder 类的一些属性与方法



    Length 属性并不是只读的。
    StringBuilder sb=new StringBuilder("I live the language");
    Console.WriteLine(sb.ToString( ));
    sb.Length = 6;
    //Displays "I live"
    Console.WriteLine(sb.ToString( ));

    Capacity 属性
    描述:当前为实例分配的字符数量。默认容量是16,如果将一个字符串作为参数提供给构造函数,容量以最接近 2 的幂的值。

    MaxCapacity 属性
    描述:这个实例中可以被分配的字符最大数量。

    Append( ) 方法
    描述:追加给定值的字符串表示。
    StringBuilder sb=new StringBuilder( );
    Console.WriteLine( sb.Capacity+"\t"+sb.Length );
    sb.Append ( 'a' , 17 )
    Console.WriteLine( sb.Capacity+"\t"+sb.Length );
    16       0 <== 输出
    32       17

    EnsureCapacity( Int capacity ) 方法
    描述:如果当前容量小于指定容量,内存分配会增加内存空间以达到指定容量。

    Replace( Char oldchar,Char newchar ) 方法
    描述:用newchar替换oldchar。

    Replace( String oldstring,String newstring ) 方法
    描述:用newstring替换oldstring。

    Replace( Char oldchar,Char newchar,Int startpos,Int count ) 方法
    描述:从startpos到count-1之间用newchar替换oldchar。

    Replace( String oldstring,String newstring,Int startpos,Int count ) 方法
    描述:从startpos到count-1之间用newstring替换oldstring。

    ToString( ) 方法
    StringBuilder sb=new StringBuilder( "I live this game" );
    String s1=sb.ToString( );         //Displays "I live this game"
    String s2=sb.ToString(3,4);     //Displays "live"
    在这里第二个ToString( )方法调用了String类的Substring( )方法
    public String ToString( int startIndex,int length )
    {
    return m_StringValue.Substring( startIndex,length );
    }

    String 类学习笔记

    一、String 类的常用公共成员



    Compare(String s1,String s2) 静态方法
    功能:区分大小写比较。

    Compare(String s1,String s2,Bool ignoreCase) 静态方法
    功能:ignoreCase为True,不区分大小写比较。

    CompareTo(String s)       实例方法
    功能:对给定字符串与实例字符串执行一次区分大小写与文化信息比较。

    Copy(String s)             静态方法
    功能:返回一个与给定字符串同值的新的字符串。

    CopyTo(Int surceIndex,char[ ] destination,Int destIndex,Int count)
    实例方法功能:此实例中的指定位置复制到 Unicode 字符数组中的指定位置。
    参数:
    sourceIndex:此实例中的字符位置。
    destination :Unicode 字符的数组。
    destIndex :destination 中的数组元素。
    count:此实例中要复制到 destination 的字符数。
    例程:
    using System;
    public class CopyToTest {
         public static void Main() {
         string strSource = "changed";
         char [] destination = { 'T', 'h', 'e', ' ', 'i', 'n', 'i', 't', 'i', 'a', 'l', ' ', 'a', 'r', 'r', 'a', 'y' };
         Console.WriteLine( destination );
        strSource.CopyTo ( 0, destination, 4, strSource.Length );
         Console.WriteLine( destination );
         strSource = "A different string";
        strSource.CopyTo ( 2, destination, 3, 9 );
         Console.WriteLine( destination ); }
        }
    输出:
    The initial array
    The changed array
    Thedifferentarray

    EndsWith(String s)
    功能:如果实例字符串是以给定的字符串结束,就返回True。

    Equals(String s)
    功能:如果实例字符串与给定的对象具有相同的值,就返回True。

    Format(IFormatProvider provider,String format,ParamArray args)
    功能:format 的一个副本,其中格式项已替换为 args 中相应 Object 实例的 String 等效项。
    参数
    provider : 一个 IFormatProvider,它提供区域性特定的格式设置信息。
    format : 包含零个或多个格式项。
    args :包含零个或多个要格式化的对象的 Object 数组。
    例如:
    string myName = "Fred";
    String.Format("Name = {0}, hours = {1:hh}", myName, DateTime.Now);
    固定文本是“Name =”和“, hours =”,格式项是“{0}”和“{1:hh}”,值为 myName 和 DateTime.Now。

    Replace(String oldstring,String newstring)
    功能:在实例字符串中用newstring替换所有oldstring。


    Split(char[] separator,int count)
    参数
    separator :分隔此实例中子字符串的 Unicode 字符数组、不包含分隔符的空数组或空引用。
    count :要返回的最大数组元素数。
    例如:
    string delimStr = " ,.:";
    char [] delimiter = delimStr.ToCharArray();
    string words = "one two,three:four.";
    string [] split = null;
    split = words.Split(delimiter, 4);
    foreach (string s in split)
    {
        Console.WriteLine("-{0}-", s);
    }
    one <==输出
    two
    three
    four.

    SubString(Int startPos,Int length)
    功能:从指定位置开始返回一个指定长度的子串。

    ToString( ) 功能:返回一个对实例字符的引用。
    ToString(IFormatProvider format)
    功能:返回一个对实例字符串的引用。

    正则表达式学习笔记(1)

    一、System.Text.RegularExpression命名空间
    1、 Regex类可以用来创建正则表达式,还提供了许多方法。
    如:Regex.Replace(string input,String pattern,string replacement);
    -------RegexOption枚举
    IgnoreCase 忽略大小写。默认情况区分大小写
    RightToLeft 从右到左查找输入字符串。
    None 不设定标志。
    MiltiLine 指定^与$可以匹配行的开头和结尾,以及字符串的开头和结尾。
    SingleLine 规定特殊字符“.”匹配任一字符。换行符除外。
    例:RegexOptions.IgnoreCase
    Regex.IsMatch(Mystring,"YWSM",RegexOptions.IgnoreCase |RegexOptions.RightToLeft):
    -------(两个主要的)类构造函数
    Regex(string pattern);
    Regex(string pattern , RegexOption options);
    例:匹配YWSM:
    static void Main(string[] args)
    { Regex myRegex=new Regex("YWSM");
         System.Console.WriteLine(myregex.IsMatch("The first three letters of "+"the alphabet are YWSM"));    }
    输出:True如需设置区分大小写可用
    Regex myRegex=new Regex("YWSM",RegexOption.IgnoreCase);
    -------IsMatch( )方法
    该方法可以测试字符串,看它是否匹配正则表达式的模式。如果发现了一次匹配,返回True,否则为False。IsMatch( )有一个静态的重载方法,使用它时可以无需显式创建一个Regex对象。

    重载形式:
    public bool Regex.IsMatch(string input );
    public bool Regex.IsMatch(string input,int startat);
    public static bool Regex.IsMatch(string input,string pattern);
    public static bool Regex.IsMatch(string input,string pattern,RegexOption options);

    input: 指定了包含将检索的文本的字符串。
    sartat: 指定了搜索的起始字符位置。
    pttern: 指定将匹配的样式。
    options: 匹配行为的选项。

    例:string inputstring="Welcome to the ywicc,ywsmxy!";
         if ( Regex.IsMatch( inputstring,"ywicc",RegexOptions.IgnoreCase) )
              Console.WriteLine("Match Found");
         Else
              Console.WriteLine(" No Match Found");
    ------Replace( )方法   
    用指定的字符串代替一个匹配模式。
    ---基本方法有:
    public static string Regex.Replace(string input,string pattern,string replacement);
    public static string Regex.Replace(string input,string pattern,string replacement,RegexOption options);
    例:用"AAA"替换"BBB"的所有实例代码:
    string inputstring="Welcome to the AAA!";
    inputstring=Regex.Replace(inputstring,"BBB","AAA");
    Console.WriteLine(inputstring);
    ----非静态方法,可以指定替换次数的最大值以及开始下标:
    Public string Replace(string input,string replacement);
    Public string Replace(string input,string replacement,int count);
    Public string Replace(string input,string replacement,int count,int startat);
    例:使用XXX替换456之后的123,最多替换两次,代码如下:
    string inputstring="123,456,123,123,123,789,333";
    Regex regexp=new Regex("123");
    Inputstring=regexp.Replace(inputstring,"XXX",2,4)
    Console.WriteLine(inputstring);
    输出:123,456,XXX,XXX,123,789,333
    -------Split( )方法
    在每次发现匹配的位置拆分字符串。返回一个字符串数组。
    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;
    class mysplit
    {
        static void Main(string[ ] args)
        {
            string inputstring="123,456,789,ads";
           string[ ] splitResults;
           splitresults=Regex.Split(inputstring,",");
           StringBuilder resultsstring=new StringBuilder(32);
             foreach(string stringelement in splitresults)
        {
                 resultsstring.Append(stringelement+"\n");
            }
            MessageBox.Show(resultsString.ToString( ));
    }
    }     

    123      <==结果
    456
    789

    MaxCapacity 属性
    描述:这个实例中可以被分配的字符最大数量。

    Append( ) 方法
    描述:追加给定值的字符串表示。
    StringBuilder sb=new StringBuilder( );
    Console.WriteLine( sb.Capacity+"\t"+sb.Length );
    sb.Append ( 'a' , 17 )
    Console.WriteLine( sb.Capacity+"\t"+sb.Length );
    16       0 <== 输出
    32       17

    EnsureCapacity( Int capacity ) 方法
    描述:如果当前容量小于指定容量,内存分配会增加内存空间以达到指定容量。

    Replace( Char oldchar,Char newchar ) 方法
    描述:用newchar替换oldchar。

    Replace( String oldstring,String newstring ) 方法
    描述:用newstring替换oldstring。

    Replace( Char oldchar,Char newchar,Int startpos,Int count ) 方法
    描述:从startpos到count-1之间用newchar替换oldchar。

    Replace( String oldstring,String newstring,Int startpos,Int count ) 方法
    描述:从startpos到count-1之间用newstring替换oldstring。

    ToString( ) 方法
    StringBuilder sb=new StringBuilder( "I live this game" );
    String s1=sb.ToString( );         //Displays "I live this game"
    String s2=sb.ToString(3,4);     //Displays "live"
    在这里第二个ToString( )方法调用了String类的Substring( )方法
    public String ToString( int startIndex,int length )
    {
    return m_StringValue.Substring( startIndex,length );
    }

    String 类学习笔记

    一、String 类的常用公共成员



    Compare(String s1,String s2) 静态方法
    功能:区分大小写比较。

    Compare(String s1,String s2,Bool ignoreCase) 静态方法
    功能:ignoreCase为True,不区分大小写比较。

    CompareTo(String s)       实例方法
    功能:对给定字符串与实例字符串执行一次区分大小写与文化信息比较。

    Copy(String s)             静态方法
    功能:返回一个与给定字符串同值的新的字符串。

    CopyTo(Int surceIndex,char[ ] destination,Int destIndex,Int count)
    实例方法功能:此实例中的指定位置复制到 Unicode 字符数组中的指定位置。
    参数:
    sourceIndex:此实例中的字符位置。
    destination :Unicode 字符的数组。
    destIndex :destination 中的数组元素。
    count:此实例中要复制到 destination 的字符数。
    例程:
    using System;
    public class CopyToTest {
         public static void Main() {
         string strSource = "changed";
         char [] destination = { 'T', 'h', 'e', ' ', 'i', 'n', 'i', 't', 'i', 'a', 'l', ' ', 'a', 'r', 'r', 'a', 'y' };
         Console.WriteLine( destination );
        strSource.CopyTo ( 0, destination, 4, strSource.Length );
         Console.WriteLine( destination );
         strSource = "A different string";
        strSource.CopyTo ( 2, destination, 3, 9 );
         Console.WriteLine( destination ); }
        }
    输出:
    The initial array
    The changed array
    Thedifferentarray

    EndsWith(String s)
    功能:如果实例字符串是以给定的字符串结束,就返回True。

    Equals(String s)
    功能:如果实例字符串与给定的对象具有相同的值,就返回True。

    Format(IFormatProvider provider,String format,ParamArray args)
    功能:format 的一个副本,其中格式项已替换为 args 中相应 Object 实例的 String 等效项。
    参数
    provider : 一个 IFormatProvider,它提供区域性特定的格式设置信息。
    format : 包含零个或多个格式项。
    args :包含零个或多个要格式化的对象的 Object 数组。
    例如:
    string myName = "Fred";
    String.Format("Name = {0}, hours = {1:hh}", myName, DateTime.Now);
    固定文本是“Name =”和“, hours =”,格式项是“{0}”和“{1:hh}”,值为 myName 和 DateTime.Now。

    Replace(String oldstring,String newstring)
    功能:在实例字符串中用newstring替换所有oldstring。


    Split(char[] separator,int count)
    参数
    separator :分隔此实例中子字符串的 Unicode 字符数组、不包含分隔符的空数组或空引用。
    count :要返回的最大数组元素数。
    例如:
    string delimStr = " ,.:";
    char [] delimiter = delimStr.ToCharArray();
    string words = "one two,three:four.";
    string [] split = null;
    split = words.Split(delimiter, 4);
    foreach (string s in split)
    {
        Console.WriteLine("-{0}-", s);
    }
    one <==输出
    two
    three
    four.

    SubString(Int startPos,Int length)
    功能:从指定位置开始返回一个指定长度的子串。

    ToString( ) 功能:返回一个对实例字符的引用。
    ToString(IFormatProvider format)
    功能:返回一个对实例字符串的引用。

    正则表达式学习笔记(1)

    一、System.Text.RegularExpression命名空间
    1、 Regex类可以用来创建正则表达式,还提供了许多方法。
    如:Regex.Replace(string input,String pattern,string replacement);
    -------RegexOption枚举
    IgnoreCase 忽略大小写。默认情况区分大小写
    RightToLeft 从右到左查找输入字符串。
    None 不设定标志。
    MiltiLine 指定^与$可以匹配行的开头和结尾,以及字符串的开头和结尾。
    SingleLine 规定特殊字符“.”匹配任一字符。换行符除外。
    例:RegexOptions.IgnoreCase
    Regex.IsMatch(Mystring,"YWSM",RegexOptions.IgnoreCase |RegexOptions.RightToLeft):
    -------(两个主要的)类构造函数
    Regex(string pattern);
    Regex(string pattern , RegexOption options);
    例:匹配YWSM:
    static void Main(string[] args)
    { Regex myRegex=new Regex("YWSM");
         System.Console.WriteLine(myregex.IsMatch("The first three letters of "+"the alphabet are YWSM"));    }
    输出:True如需设置区分大小写可用
    Regex myRegex=new Regex("YWSM",RegexOption.IgnoreCase);
    -------IsMatch( )方法
    该方法可以测试字符串,看它是否匹配正则表达式的模式。如果发现了一次匹配,返回True,否则为False。IsMatch( )有一个静态的重载方法,使用它时可以无需显式创建一个Regex对象。

    重载形式:
    public bool Regex.IsMatch(string input );
    public bool Regex.IsMatch(string input,int startat);
    public static bool Regex.IsMatch(string input,string pattern);
    public static bool Regex.IsMatch(string input,string pattern,RegexOption options);

    input: 指定了包含将检索的文本的字符串。
    sartat: 指定了搜索的起始字符位置。
    pttern: 指定将匹配的样式。
    options: 匹配行为的选项。

    例:string inputstring="Welcome to the ywicc,ywsmxy!";
         if ( Regex.IsMatch( inputstring,"ywicc",RegexOptions.IgnoreCase) )
              Console.WriteLine("Match Found");
         Else
              Console.WriteLine(" No Match Found");
    ------Replace( )方法   
    用指定的字符串代替一个匹配模式。
    ---基本方法有:
    public static string Regex.Replace(string input,string pattern,string replacement);
    public static string Regex.Replace(string input,string pattern,string replacement,RegexOption options);
    例:用"AAA"替换"BBB"的所有实例代码:
    string inputstring="Welcome to the AAA!";
    inputstring=Regex.Replace(inputstring,"BBB","AAA");
    Console.WriteLine(inputstring);
    ----非静态方法,可以指定替换次数的最大值以及开始下标:
    Public string Replace(string input,string replacement);
    Public string Replace(string input,string replacement,int count);
    Public string Replace(string input,string replacement,int count,int startat);
    例:使用XXX替换456之后的123,最多替换两次,代码如下:
    string inputstring="123,456,123,123,123,789,333";
    Regex regexp=new Regex("123");
    Inputstring=regexp.Replace(inputstring,"XXX",2,4)
    Console.WriteLine(inputstring);
    输出:123,456,XXX,XXX,123,789,333
    -------Split( )方法
    在每次发现匹配的位置拆分字符串。返回一个字符串数组。
    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;
    class mysplit
    {
        static void Main(string[ ] args)
        {
            string inputstring="123,456,789,ads";
           string[ ] splitResults;
           splitresults=Regex.Split(inputstring,",");
           StringBuilder resultsstring=new StringBuilder(32);
             foreach(string stringelement in splitresults)
        {
                 resultsstring.Append(stringelement+"\n");
            }
            MessageBox.Show(resultsString.ToString( ));
    }
    }     

    123      <==结果
    456
    789
    ads

    < p>
    < p>< p>
  • [StructLayout(LayoutKind.Sequential)](转载)

    2009-07-16 00:04:50

    [StructLayout(LayoutKind.Sequential)] 是什么意思??
    2008-09-26 09:52
    结构体是由若干成员组成的.布局有两种 
    1.Sequential,顺序布局,比如 
    struct S1 
    { 
    int a; 
    int b; 
    } 
    那么默认情况下在内存里是先排a,再排b 
    也就是如果能取到a的地址,和b的地址,则相差一个int类型的长度,4字节 
    [StructLayout(LayoutKind.Sequential)] 
    struct S1 
    { 
    int a; 
    int b; 
    } 
    这样和上一个是一样的.因为默认的内存排列就是Sequential,也就是按成员的先后顺序排列. 
    2.Explicit,精确布局 
    需要用FieldOffset()设置每个成员的位置 
    这样就可以实现类似c的公用体的功能 
    [StructLayout(LayoutKind.Explicit)] 
    struct S1 
    { 
    [FieldOffset(0)] 
    int a; 
    [FieldOffset(0)] 
    int b; 
    } 
    这样a和b在内存中地址相同
  • which and that(转载)

    2009-07-14 10:02:23

    只能用that的情况:
    <1>关系代词在定语从句中作表语,不管是人或物只能用that。
    He is not the man  that  he  was  when I first saw him.
    【他现在不是我第一次见他时那样的。】


    <2>当先行词即指物又指人时,多用that引导定语从句。
    Look at the  girl  and the  dog  that  are crossing the street.
    【瞧正在过马路的那个女孩和那只狗。】


    <3>当先行词是有生命的动物或人时,宜使用that而不是which。
    1.What's the name of the  animals  that  jumps about?
    【四处蹦跳的动物叫什么名字?】
    2.Who is the  girl  that  talked to you yesterday?
    【昨天和你说话的女孩儿是谁?】


    <4>当先行词被形容词的最高级修饰时引导定语从句的关系代词只能用that,而不能用which。
    This is  the most  interesting book  that  I've ever read.
    【这是我所读过的最有趣的书。】


    <5>当先行词被all,something,anything,nothing,everything,little,much,the one,none等时,引导定语从句多用关系代词that。
    1.The goverment has promised to do  all  that  lies in its power to alleviate the hardships of people.
    【政府承诺尽其一切力量减轻人民的苦难。】
    2.When we see  anything  that  happen on the island, we're so glad.
    【当我们看到岛上发生的事情,我们都如此兴奋。】
    3.Tom told his father  all  that  had happened.
    【汤姆把事情发生的全部情况都告诉了他的父亲。】
    4.Pay attention to  everything  that  I do.
    【注意我做的每一件事。】
    5.The teacher wants to teach us  all  that  he knows.
    【老师想把他知道的全部知识都交给我们。】
    6.You must do  everything  that  I do.
    【我做的每件事你必须都做。】


    <6>当先行词被the only, the very, the first,the last,few,little,no,all,one of,the same等修饰时,须用关系代词that来引导。
    The only  thing  that  we can do is to give you some money.
    【我们唯一能够做的就是给你一些钱。】


    <7>当主句中已有疑问词who或which时,要用关系代词that。
    Which  is the bik e  that  you lost?
    【你丢失的自行车是哪辆?】



    只能用which的情况:
    <8>在介词后面的关系代词用which而不能用that。即“介词+which(代物)”
    1.The picture   for   which  he paid $1,000 was once owned by a duke.
    【他花了1000美元买下的画曾为一名公爵所拥有。】
    2.The building   in  which  Han Mei studied was very old.
    【韩梅在里边学习的那幢大楼很旧。】


    <9>在非限定性定语从句中不能用that。
    Crusoe's dog,  which  was very old now, became ill and died.
    【克鲁索的狗,现在已经很老了,病死了。】


    <10>有两个定语从句,其中一个关系代词已有which,另一个宜用that。相反,如果其中一个为that,另一个宜用which。
    1.Edison built up a factory   which  produced things 

     
    that  had never been seen before.
    【爱迪生办了一个工厂,生产过去从未见过的东西。】
    2.Let me show you the novel   that  I borrowed from the library  which  was newly open to us.
    【让我给你看看我从新开放的图书馆借来的小说。】



    共同点:
    <11>当定语从句所修饰的先行词为物时,关系代词可用which或that。
    1.In fact the Swede did not understand the three  questions  that/which  were asked in English.
    【事实上Swede并不理解三个被提问到的英语问题。】
    2.Colour the  birds   which/that  are flying.
    【给那些正在飞着的鸟上色。】
    3.The  pen  that/which  I am using is quiet good.
    【我正在使用的那支钢笔相当好。】
    4.The  film  which/that  we saw last night was wonderful!
    【昨晚我们看的那部影片真棒!】
  • 字符,字节和编码(转载)

    2009-06-22 22:54:07

    字符,字节和编码(转载)

    级别:中级

    摘要:本文介绍了字符与编码的发展过程,相关概念的正确理解。举例说明了一些实际应用中,编码的实现方法。然后,本文讲述了通常对字符与编码的几种误解,由于这些误解而导致乱码产生的原因,以及消除乱码的办法。本文的内容涵盖了“中文问题”,“乱码问题”。

    掌握编码问题的关键是正确地理解相关概念,编码所涉及的技术其实是很简单的。因此,阅读本文时需要慢读多想,多思考。

    引言

    “字符与编码”是一个被经常讨论的话题。即使这样,时常出现的乱码仍然困扰着大家。虽然我们有很多的办法可以用来消除乱码,但我们并不一定理解这些办法的内在原理。而有的乱码产生的原因,实际上由于底层代码本身有问题所导致的。因此,不仅是初学者会对字符编码感到模糊,有的底层开发人员同样对字符编码缺乏准确的理解。

    回页首

    1. 编码问题的由来,相关概念的理解

    1.1 字符与编码的发展

    从计算机对多国语言的支持角度看,大致可以分为三个阶段:

      系统内码 说明 系统
    阶段一 ASCII 计算机刚开始只支持英语,其它语言不能够在计算机上存储和显示。 英文 DOS
    阶段二 ANSI编码
    (本地化)
    为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。

    不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。

    不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。
    中文 DOS,中文 Windows 95/98,日文 Windows 95/98
    阶段三 UNICODE
    (国际化)
    为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。 Windows NT/2000/XP,Linux,Java

    字符串在内存中的存放方法:

    在 ASCII 阶段,单字节字符串使用一个字节存放一个字符(SBCS)。比如,"Bob123" 在内存中为:

    42 6F 62 31 32 33 00
    B o b 1 2 3 \0

    在使用 ANSI 编码支持多种语言阶段,每个字符使用一个字节或多个字节来表示(MBCS),因此,这种方式存放的字符也被称作多字节字符。比如,"中文123" 在中文 Windows 95 内存中为7个字节,每个汉字占2个字节,每个英文和数字字符占1个字节:

    D6 D0 CE C4 31 32 33 00
    1 2 3 \0

    在 UNICODE 被采用之后,计算机存放字符串时,改为存放每个字符在 UNICODE 字符集中的序号。目前计算机一般使用 2 个字节(16 位)来存放一个序号(DBCS),因此,这种方式存放的字符也被称作宽字节字符。比如,字符串 "中文123" 在 Windows 2000 下,内存中实际存放的是 5 个序号:

    2D 4E 87 65 31 00 32 00 33 00 00 00      ← 在 x86 CPU 中,低字节在前
    1 2 3 \0  

    一共占 10 个字节。

    回页首

    1.2 字符,字节,字符串

    理解编码的关键,是要把字符的概念和字节的概念理解准确。这两个概念容易混淆,我们在此做一下区分:

      概念描述 举例
    字符 人们使用的记号,抽象意义上的一个符号。 '1', '中', 'a', '$', '¥', ……
    字节 计算机中存储数据的单元,一个8位的二进制数,是一个很具体的存储空间。 0x01, 0x45, 0xFA, ……
    ANSI
    字符串
    在内存中,如果“字符”是以 ANSI 编码形式存在的,一个字符可能使用一个字节或多个字节来表示,那么我们称这种字符串为 ANSI 字符串或者多字节字符串 "中文123"
    (占7字节)
    UNICODE
    字符串
    在内存中,如果“字符”是以在 UNICODE 中的序号存在的,那么我们称这种字符串为 UNICODE 字符串或者宽字节字符串 L"中文123"
    (占10字节)

    由于不同 ANSI 编码所规定的标准是不相同的,因此,对于一个给定的多字节字符串,我们必须知道它采用的是哪一种编码规则,才能够知道它包含了哪些“字符”。而对于 UNICODE 字符串来说,不管在什么环境下,它所代表的“字符”内容总是不变的。

    回页首

    1.3 字符集与编码

    各个国家和地区所制定的不同 ANSI 编码标准中,都只规定了各自语言所需的“字符”。比如:汉字标准(GB2312)中没有规定韩国语字符怎样存储。这些 ANSI 编码标准所规定的内容包含两层含义:

    1. 使用哪些字符。也就是说哪些汉字,字母和符号会被收入标准中。所包含“字符”的集合就叫做“字符集”。
    2. 规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储,这个规定就叫做“编码”。

    各个国家和地区在制定编码标准的时候,“字符的集合”和“编码”一般都是同时制定的。因此,平常我们所说的“字符集”,比如:GB2312, GBK, JIS 等,除了有“字符的集合”这层含义外,同时也包含了“编码”的含义。

    UNICODE 字符集”包含了各种语言中使用到的所有“字符”。用来给 UNICODE 字符集编码的标准有很多种,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等。

    回页首

    1.4 常用的编码简介

    简单介绍一下常用的编码规则,为后边的章节做一个准备。在这里,我们根据编码规则的特点,把所有的编码分成三类:

    分类 编码标准 说明
    单字节字符编码 ISO-8859-1 最简单的编码规则,每一个字节直接作为一个 UNICODE 字符。比如,[0xD6, 0xD0] 这两个字节,通过 iso-8859-1 转化为字符串时,将直接得到 [0x00D6, 0x00D0] 两个 UNICODE 字符,即 "ÖÐ"。

    反之,将 UNICODE 字符串通过 iso-8859-1 转化为字节串时,只能正常转化 0~255 范围的字符。
    ANSI 编码 GB2312,
    BIG5,
    Shift_JIS,
    ISO-8859-2 ……
    把 UNICODE 字符串通过 ANSI 编码转化为“字节串”时,根据各自编码的规定,一个 UNICODE 字符可能转化成一个字节或多个字节。

    反之,将字节串转化成字符串时,也可能多个字节转化成一个字符。比如,[0xD6, 0xD0] 这两个字节,通过 GB2312 转化为字符串时,将得到 [0x4E2D] 一个字符,即 '中' 字。

    “ANSI 编码”的特点:
    1. 这些“ANSI 编码标准”都只能处理各自语言范围之内的 UNICODE 字符。
    2. “UNICODE 字符”与“转换出来的字节”之间的关系是人为规定的。
    UNICODE 编码 UTF-8,
    UTF-16, UnicodeBig ……
    与“ANSI 编码”类似的,把字符串通过 UNICODE 编码转化成“字节串”时,一个 UNICODE 字符可能转化成一个字节或多个字节。

    与“ANSI 编码”不同的是:
    1. 这些“UNICODE 编码”能够处理所有的 UNICODE 字符。
    2. “UNICODE 字符”与“转换出来的字节”之间是可以通过计算得到的。

    我们实际上没有必要去深究每一种编码具体把某一个字符编码成了哪几个字节,我们只需要知道“编码”的概念就是把“字符”转化成“字节”就可以了。对于“UNICODE 编码”,由于它们是可以通过计算得到的,因此,在特殊的场合,我们可以去了解某一种“UNICODE 编码”是怎样的规则。

    回页首

    2. 字符与编码在程序中的实现

    2.1 程序中的字符与字节

    在 C++ 和 Java 中,用来代表“字符”和“字节”的数据类型,以及进行编码的方法:

    类型或操作 C++ Java
    字符 wchar_t char
    字节 char byte
    ANSI 字符串 char[] byte[]
    UNICODE 字符串 wchar_t[] String
    字节串→字符串 mbstowcs(), MultiByteToWideChar() string = new String(bytes, "encoding")
    字符串→字节串 wcstombs(), WideCharToMultiByte() bytes = string.getBytes("encoding")

    以上需要注意几点:

    1. Java 中的 char 代表一个“UNICODE 字符(宽字节字符)”,而 C++ 中的 char 代表一个字节。
    2. MultiByteToWideChar() 和 WideCharToMultiByte() 是 Windows API 函数。

    回页首

    2.2 C++ 中相关实现方法

    声明一段字符串常量:

    // ANSI 字符串,内容长度 7 字节
    char
         sz[20] = "中文123";

    // UNICODE 字符串,内容长度 5 个 wchar_t(10 字节)
    wchar_t wsz[20] = L"\x4E2D\x6587\x0031\x0032\x0033";

    UNICODE 字符串的 I/O 操作,字符与字节的转换操作:

    // 运行时设定当前 ANSI 编码,VC 格式
    setlocale(LC_ALL, ".936");

    // GCC 中格式
    setlocale(LC_ALL, "zh_CN.GBK");

    // Visual C++ 中使用小写 %s,按照 setlocale 指定编码输出到文件
    // GCC 中使用大写 %S

    fwprintf(fp, L"%s\n", wsz);

    // 把 UNICODE 字符串按照 setlocale 指定的编码转换成字节
    wcstombs(sz, wsz, 20);
    // 把字节串按照 setlocale 指定的编码转换成 UNICODE 字符串
    mbstowcs(wsz, sz, 20);

    在 Visual C++ 中,UNICODE 字符串常量有更简单的表示方法。如果源程序的编码与当前默认 ANSI 编码不符,则需要使用 #pragma setlocale,告诉编译器源程序使用的编码:

    // 如果源程序的编码与当前默认 ANSI 编码不一致,
    // 则需要此行,编译时用来指明当前源程序使用的编码

    #pragma setlocale
    (".936")

    // UNICODE 字符串常量,内容长度 10 字节
    wchar_t wsz[20] = L"中文123";

    以上需要注意 #pragma setlocale 与 setlocale(LC_ALL, "") 的作用是不同的,#pragma setlocale 在编译时起作用,setlocale() 在运行时起作用。

    回页首

    2.3 Java 中相关实现方法

    字符串类 String 中的内容是 UNICODE 字符串:

    // Java 代码,直接写中文
    String
    string = "中文123";

    // 得到长度为 5,因为是 5 个字符
    System.out.println(string.length());

    字符串 I/O 操作,字符与字节转换操作。在 Java 包 java.io.* 中,以“Stream”结尾的类一般是用来操作“字节串”的类,以“Reader”,“Writer”结尾的类一般是用来操作“字符串”的类。

    // 字符串与字节串间相互转化

    // 按照 GB2312 得到字节(得到多字节字符串)

    byte
    [] bytes = string.getBytes("GB2312");

    // 从字节按照 GB2312 得到 UNICODE 字符串
    string = new String(bytes, "GB2312");

    // 要将 String 按照某种编码写入文本文件,有两种方法:

    // 第一种办法:用 Stream 类写入已经按照指定编码转化好的字节串

    OutputStream s = new FileOutputStream("1.txt");
    os.write(bytes);
    os.close();

    // 第二种办法:构造指定编码的 Writer 来写入字符串
    Writer w = new OutputStreamWriter(new FileOutputStream("2.txt"), "GB2312");
    ow.write(string);
    ow.close();

    /* 最后得到的 1.txt 和 2.txt 都是 7 个字节 */

    如果 java 的源程序编码与当前默认 ANSI 编码不符,则在编译的时候,需要指明一下源程序的编码。比如:

    E:\>javac -encoding BIG5 Hello.java

    以上需要注意区分源程序的编码与 I/O 操作的编码,前者是在编译时起作用,后者是在运行时起作用。

    回页首

    3. 几种误解,以及乱码产生的原因和解决办法

    3.1 容易产生的误解
      对编码的误解
    误解一 在将“字节串”转化成“UNICODE 字符串”时,比如在读取文本文件时,或者通过网络传输文本时,容易将“字节串”简单地作为单字节字符串,采用每“一个字节”就是“一个字符”的方法进行转化。

    而实际上,在非英文的环境中,应该将“字节串”作为 ANSI 字符串,采用适当的编码来得到 UNICODE 字符串,有可能“多个字节”才能得到“一个字符”。

    通常,一直在英文环境下做开发的程序员们,容易有这种误解。
    误解二 在 DOS,Windows 98 等非 UNICODE 环境下,字符串都是以 ANSI 编码的字节形式存在的。这种以字节形式存在的字符串,必须知道是哪种编码才能被正确地使用。这使我们形成了一个惯性思维:“字符串的编码”。

    当 UNICODE 被支持后,Java 中的 String 是以字符的“序号”来存储的,不是以“某种编码的字节”来存储的,因此已经不存在“字符串的编码”这个概念了。只有在“字符串”与“字节串”转化时,或者,将一个“字节串”当成一个 ANSI 字符串时,才有编码的概念。

    不少的人都有这个误解。

    第一种误解,往往是导致乱码产生的原因。第二种误解,往往导致本来容易纠正的乱码问题变得更复杂。

    在这里,我们可以看到,其中所讲的“误解一”,即采用每“一个字节”就是“一个字符”的转化方法,实际上也就等同于采用 iso-8859-1 进行转化。因此,我们常常使用 bytes = string.getBytes("iso-8859-1") 来进行逆向操作,得到原始的“字节串”。然后再使用正确的 ANSI 编码,比如 string = new String(bytes, "GB2312"),来得到正确的“UNICODE 字符串”。

    回页首

    3.2 非 UNICODE 程序在不同语言环境间移植时的乱码

    非 UNICODE 程序中的字符串,都是以某种 ANSI 编码形式存在的。如果程序运行时的语言环境与开发时的语言环境不同,将会导致 ANSI 字符串的显示失败。

    比如,在日文环境下开发的非 UNICODE 的日文程序界面,拿到中文环境下运行时,界面上将显示乱码。如果这个日文程序界面改为采用 UNICODE 来记录字符串,那么当在中文环境下运行时,界面上将可以显示正常的日文。

    由于客观原因,有时候我们必须在中文操作系统下运行非 UNICODE 的日文软件,这时我们可以采用一些工具,比如,南极星,AppLocale 等,暂时的模拟不同的语言环境。

    回页首

    3.3 网页提交字符串

    当页面中的表单提交字符串时,首先把字符串按照当前页面的编码,转化成字节串。然后再将每个字节转化成 "%XX" 的格式提交到 Web 服务器。比如,一个编码为 GB2312 的页面,提交 "中" 这个字符串时,提交给服务器的内容为 "%D6%D0"。

    在服务器端,Web 服务器把收到的 "%D6%D0" 转化成 [0xD6, 0xD0] 两个字节,然后再根据 GB2312 编码规则得到 "中" 字。

    在 Tomcat 服务器中,request.getParameter() 得到乱码时,常常是因为前面提到的“误解一”造成的。默认情况下,当提交 "%D6%D0" 给 Tomcat 服务器时,request.getParameter() 将返回 [0x00D6, 0x00D0] 两个 UNICODE 字符,而不是返回一个 "中" 字符。因此,我们需要使用 bytes = string.getBytes("iso-8859-1") 得到原始的字节串,再用 string = new String(bytes, "GB2312") 重新得到正确的字符串 "中"。

    回页首

    3.4 从数据库读取字符串

    通过数据库客户端(比如 ODBC 或 JDBC)从数据库服务器中读取字符串时,客户端需要从服务器获知所使用的 ANSI 编码。当数据库服务器发送字节流给客户端时,客户端负责将字节流按照正确的编码转化成 UNICODE 字符串。

    如果从数据库读取字符串时得到乱码,而数据库中存放的数据又是正确的,那么往往还是因为前面提到的“误解一”造成的。解决的办法还是通过 string = new String( string.getBytes("iso-8859-1"), "GB2312") 的方法,重新得到原始的字节串,再重新使用正确的编码转化成字符串。

    回页首

    3.5 电子邮件中的字符串

    当一段 Text 或者 HTML 通过电子邮件传送时,发送的内容首先通过一种指定的字符编码转化成“字节串”,然后再把“字节串”通过一种指定的传输编码(Content-Transfer-Encoding)进行转化得到另一串“字节串”。比如,打开一封电子邮件源代码,可以看到类似的内容:

    Content-Type: text/plain;
            charset="gb2312"
    Content-Transfer-Encoding: base64

    sbG+qcrQuqO17cf4yee74bGjz9W7+b3wudzA7dbQ0MQNCg0KvPKzxqO6uqO17cnnsaPW0NDEDQoNCg==

    最常用的 Content-Transfer-Encoding 有 Base64 和 Quoted-Printable 两种。在对二进制文件或者中文文本进行转化时,Base64 得到的“字节串”比 Quoted-Printable 更短。在对英文文本进行转化时,Quoted-Printable 得到的“字节串”比 Base64 更短。

    邮件的标题,用了一种更简短的格式来标注“字符编码”和“传输编码”。比如,标题内容为 "中",则在邮件源代码中表示为:

    // 正确的标题格式
    Subject: =?GB2312?B?1tA=?=

    其中,

    • 第一个“=?”与“?”中间的部分指定了字符编码,在这个例子中指定的是 GB2312。
    • “?”与“?”中间的“B”代表 Base64。如果是“Q”则代表 Quoted-Printable。
    • 最后“?”与“?=”之间的部分,就是经过 GB2312 转化成字节串,再经过 Base64 转化后的标题内容。

    如果“传输编码”改为 Quoted-Printable,同样,如果标题内容为 "中":

    // 正确的标题格式
    Subject: =?GB2312?Q?=D6=D0?=

    如果阅读邮件时出现乱码,一般是因为“字符编码”或“传输编码”指定有误,或者是没有指定。比如,有的发邮件组件在发送邮件时,标题 "中":

    // 错误的标题格式
    Subject: =?ISO-8859-1?Q?=D6=D0?=

    这样的表示,实际上是明确指明了标题为 [0x00D6, 0x00D0],即 "ÖÐ",而不是 "中"。

    回页首

    4. 几种错误理解的纠正

    误解:“ISO-8859-1 是国际编码?”

    非也。iso-8859-1 只是单字节字符集中最简单的一种,也就是“字节编号”与“UNICODE 字符编号”一致的那种编码规则。当我们要把一个“字节串”转化成“字符串”,而又不知道它是哪一种 ANSI 编码时,先暂时地把“每一个字节”作为“一个字符”进行转化,不会造成信息丢失。然后再使用 bytes = string.getBytes("iso-8859-1") 的方法可恢复到原始的字节串。

    误解:“Java 中,怎样知道某个字符串的内码?”

    Java 中,字符串类 java.lang.String 处理的是 UNICODE 字符串,不是 ANSI 字符串。我们只需要把字符串作为“抽象的符号的串”来看待。因此不存在字符串的内码的问题

  • 非谓语动词做定语(转载)

    2009-06-10 13:02:30

    2009-01-14 10:44:26  作者:南开中学 李士明  来源:城市快报  点击:134  文字大小:[][][]
    简介:非谓语动词做定语直接修饰名词的成分称为定语,一般由形容词或名词担当,也可以分别由不定式、分词或 ...

    非谓语动词做定语

    直接修饰名词的成分称为定语,一般由形容词或名词担当,也可以分别由不定式、分词或动名词等非谓语动词来担当。那么如何区别并正确使用非谓语动词呢?

    NON-FINITES

    1. 现在分词与过去分词的区别

    我们知道非谓语动词都源于及物和不及物两种谓语动词,要了解现在分词与过去分词的区别就要从谓语动词的基本属性开始。

    1)及物动词 (v.t.)

    及物动词的主语我们称为动作的发出者(sender),宾语称为动作的承受者(receiver)。

    例如:

    The news surprised

    动词+ing (发出者) 及物动词v.t.

    the students.

    动词+ed (承受者)

    Surprise是及物动词, 在使用surprise这个动词的非谓语分词形式时,修饰动作发出者news用现在分词形式(动词+ing),修饰动作的承受者用过去分词形式(动词+ed)。

    ●They are talking about the surprising news. (surprising做定语修饰发出者news)

    The news is surprising. (surprising做表语修饰发出者news)

    They are talking about the surprised students. (surprised做定语修饰承受者students)

    The students are surprised. (surprised做表语修饰承受者students)

    再来看几个例子:

    ●exciting games激烈精彩的比赛, excited spectators激情振奋的观众

    ●disappointing results令人沮丧的结果, disappointed people大失所望的人们

    ●exhausting work令人疲惫不堪的工作, exhausted workers筋疲力尽的工人

    ●moving stories感人肺腑的故事, moved students感激涕零的学生

    从以上例子可见,现在分词和过去分词都可以用作形容词来修饰名词,修饰动作发出者用现在分词,修饰动作承受者用过去分词。要特别注意的是,依据被修饰的名词是人还是物来判断现在分词和过去分词的用法是不准确的。

    例如: They complicated the situation by introducing some more restriction.

    他们采用了一些更多的限制把形势复杂化了。

    及物动词complicate的发出者是人they, 而承受者是物。因此,“复杂恶化的形势”应译为the complicated situation,“形势是令人棘手的” 应译为The situation is complicated.

    从这个例子可以清楚地看出,如果根据中文,很容易将“令人棘手的形势”错误地理解为 “complicating situation”。

    再比如我们常用的:

    a broken cup 一个破杯子; spoken English英语口语;exported products出口产品。

    因此,准确了解所修饰的名词与及物动词的关系,是正确使用及物动词的现在分词和过去分词的关键。

    2) 不及物动词(v.i.)

    不及物动词只有动作的发出者,不存在动作的承受者。因此,不及物动词的现在分词源于进行时,表示动作正在进行,而过去分词则源于完成时,表示动作已完成。

    例如:

    ●He looked at the leaves which are falling in the air.(从句用进行时修饰名词the leaves)

    他看着空气中飘然下落的叶子。

    =He looked at the leaves falling in the air.(现在分词短语修饰名词the leaves表示进行)

    =He looked at the falling leaves in the air. (现在分词修饰名词the leaves表示进行)

    ●He walked on the leaves which had fallen on the ground.(从句用完成时修饰名词the leaves) 他走在地面的落叶上。

    He walked on the leaves fallen on the ground.(过去分词短语修饰名词leaves表示过去)

    He walked on the fallen leaves on the ground. (过去分词修饰名词leaves表示过去)

    ●the rising sun. = the sun that is rising. 冉冉升起的太阳

    the risen sun = the sun that has risen. 已经升在天空的太阳

    ●boiling water = water which is boiling. 沸腾的水

    boiled water = water which has boiled 开过的水

    2. 不同形式不定式做定语的区别

    动词不定式的一般式可以用做形容词,担当名词的定语, 表示将要发生的动作,不定式的进行式和完成式都不可以用作定语。

    1)及物动词不定式一般式主动to do sth和被动to be done 两种形式的区别。

    例如:

    ●Have you anything to send? = Have you anything that you will send?

    你有什么东西要(自己)寄吗?(主动含义,动作由you自己去完成)

    (to send做定语, 源于定语从句that you will send, 修饰先行词anything, 表示将来。)

    ●Have you anything to be sent (by others)?=Have you anything that will be sent(by others)?

    你有什么东西要(我或别人)寄吗?(被动含义,动作由他人others去完成)

    (to be sent做定语, 源于定语从句that will be sent, 修饰先行词anything, 表示将来。)

    从以上两个例子可以看出,不定式的主动形式to send来源于主动语态的定语从句。

    而不定式的被动形式to be sent来源于被动语态的定语从句, 不能错误地认为to send 是主动形式表示被动,准确地讲应该牢记主动形式的不定式源于主动语态的从句,被动形式的不定式则源于被动语态的从句,两者绝不可以混淆。

    ●I have some books for you to read. = I have some books that you should read.

    我有几本书希望你读一读。

    (for you to read做定语, 源于定语从句that you should read, 修饰先行词books, 表示将来。原从句的主语you在不定式的前面以for you 的形式出现,担当不定式的逻辑主语。)

    2)不及物动词不定式一般式做定语

    当不及物动词做定语时, 后面必须有相应的介词与前面所修饰的名词相呼应, 从汉语角度理解,而忽略了必要的介词是不及物动词做定语时常见的错误。

    例如:

    ●He is looking for a room to live in.= He is looking for a room which he will live in.

    他现在正在找房间住。

    (to live in做定语, 源于定语从句which he will live in, 修饰先行词room, 表示将来。)

    ●Would you like to have another pen to write with? ( to write with the pen)

    你需要再准备一支笔用吗?

    ●Smith is a good man to work with. ( to work with the man)

    与史密斯一起工作是再好不过了。

    ●Lei Feng is a brilliant example for us to learn from. ( to learn from the example)

    雷锋是我们学习的光辉榜样。

    ●Can you lend me a chair to sit on?

    您可以借给我一把椅子坐吗?

    ●Global Financial Crisis is a hot topic to talk about today. ( to talk about the topic)

    全球性金融危机是当前人们谈论的热点话题。

  • abstract、virtual、override 和 new(转载)

    2009-05-27 14:34:34

     

    作者:阳春三月

       abstract、virtual、override 和 new 是在类的继承关系中常用的四个修饰方法的关键字,在此略作总结。

    1. 常用的中文名:abstract 抽象方法,virtual 虚方法,override 覆盖基类方法,new 隐藏基类方法,override 和 new 有时都叫重写基类方法。

    2. 适用场合:abstract 和 virtual 用在基类(父类)中;override 和 new 用在派生类(子类)中。

    3. 具体概念:

        abstract 抽象方法,是空方法,没有方法体,派生类必须以 override 实现此方法。

        virtual 虚方法,若希望或预料到基类的这个方法在将来的派生类中会被重写(override 或 new),则此方法必须被声明为 virtual。

        override 重写继承自基类的 virtural 方法,可以理解为拆掉老房子,在原址上建新房子,老房子再也找不到了(基类方法永远调用不到了)。

        new 隐藏继承自基类的 virtual 方法,老房子还留着,在旁边盖个新房,想住新房住新房(作为派生类对象调用),想住老房住老房(作为基类对象调用)。

        当派生类中出现与基类同名的方法,而此方法前面未加 override 或 new 修饰符时,编译器会报警告,但不报错,真正执行时等同于加了 new。

    4. abstract 和 virtual 的区别:abstract 方法还没实现,连累着基类也不能被实例化,除了作为一种规则或符号外没啥用;virtual 则比较好,派生类想重写就重写,不想重写就吃老子的。而且继承再好也是少用为妙,继承层次越少越好,派生类新扩展的功能越少越好,virtual 深合此意。

    5. override 和 new 的区别:当派生类对象作为基类类型使用时,override 的执行派生类方法,new 的执行基类方法。如果作为派生类类型调用,则都是执行 override 或 new 之后的。


    演示 override 和 new 区别的例子:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    namespace ConsoleApplication1

    {

    class Program

    {

    class Car

    {

    public virtual void D()

    {

    Console.WriteLine("base");

    }

    }

    class ConvertibalCar : Car

    {

    public new void D()

    {

    base.D();

    Console.WriteLine("convertibalcar");

    }

    }

    class Minivan : Car

    {

    public override void D()

    {

    base.D();

    Console.WriteLine("Minivan");

    }

    }

    static void Main(string[] args)

    {

    Car car1 = new Car();

    car1.D();

    Console.WriteLine("0000000000000");

    ConvertibalCar car2 = new ConvertibalCar();

    car2.D();

    Console.WriteLine("000000000000");

    Minivan car3 = new Minivan();

    car3.D();

    }

    }

    }

     

    输出类似如下所示:

    Four wheels and an engine.

    ----------

    Four wheels and an engine.

    A roof that opens up.

    ----------

    Four wheels and an engine.

    Carries seven people.

    ----------

    但是,如果我们声明一个从 Car 基类派生的对象的数组。此数组能够存储 Car、ConvertibleCar 和 Minivan 对象,如下所示:


    public static void TestCars2()
    {
        Car[] cars 
    = new Car[3];
        cars[
    0= new Car();
        cars[
    1= new ConvertibleCar();

        cars[2] = new Minivan();

    }

     

    然后用一个 foreach 循环来访问该数组中包含的每个 Car 对象,并调用 DescribeCar 方法,如下所示:


    foreach (Car vehicle in cars)
    {
      System.Console.WriteLine(
    "Car object: " + vehicle.GetType());
      vehicle.DescribeCar();

      System.Console.WriteLine("----------");

    }

     

    此循环的输出如下所示:

    Car object: YourApplication.Car

    Four wheels and an engine.

    ----------

    Car object: YourApplication.ConvertibleCar

    Four wheels and an engine.

    ----------

    Car object: YourApplication.Minivan

    Four wheels and an engine.

    Carries seven people.

    ----------

    注意,ConvertibleCar 的说明可能与您的预期不同。由于使用了 new 关键字来定义此方法,所调用的不是派生类方法,而是基类方法。Minivan 对象正确地调用重写方法,并产生预期的结果。

     
  • how to make asp.net 2.0 available in IIS

    2009-03-24 11:48:47

    1. In cmd, navigate to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

    2. Run aspnet_regiis -i

     

  • 迷茫

    2009-02-05 22:05:07

    暂无
  • 成长的家园

    2009-01-06 22:20:49

    工作快一年了,一直在做manual的测试。自己觉得manual的测试已经能学的东西很少了,进步的空间也很小了。再一直做下去的话也是重复性的工作。虽然知道工作一般都是做重复性的工作。但还是希望自己能进步;希望明天的自己比今天的自己前进了一小步。所以来到这里,希望能和大家一起成长。本来已经不求上进,麻木了很长时间。可是现在经济危机了,今天过去了,就不知道明天还有没有工作。所以要好好工作,好好学习。对2009的计划主要是学习一些自动化的知识和提高英语听说的能力。但具体学自动化的情况,还有点迷惑,正在思考......

Open Toolbar