Regex ใน C#

  1. การแทนที่ white-space ด้วยช่องว่าง 1 ช่อง
  2. การหา url จาก HREFs
  3. การเปลี่ยน Date Formats
  4. การหา protocol และ Port Number จาก URL
  5. นำ Invalid Characters ออกจาก String
  6. ตรวจสอบ email ว่า format ถูกต้องมั๊ย
  7. extract string ด้วย regex
  8. ตรวจสอบว่ามีเฉพาะตัวเลขเท่านั้น

1.การแทนที่ white-space ด้วยช่องว่าง 1 ช่อง

การแทนที่ white-space characters ทั้งหลาย \t, \r, \n, SPACE (ASCII 32) ด้วยช่องว่าง 1 ช่อง

using System;
using System.Text.RegularExpressions;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string st = @"Content 1
Content         2
Content     3
Content   4
Content 5";
            string st1 = Regex.Replace(st, @"\s+", " ");
            string st2 = Regex.Replace(st, @"\s+", "");
            Console.WriteLine(st1);
            Console.WriteLine(st2);
        }
    }
}

บรรทัดที่ 15,16 \s+ Match one or more white-space characters.

รันจะได้ st1 จะมีช่องว่างแต่ละอันกว้าง 1 ช่อง และ st2 ไม่มีช่องว่างเหลือ

Content 1 Content 2 Content 3 Content 4 Content 5
Content1Content2Content3Content4Content5

2.การหา url จาก HREFs

private static void DumpHRefs(string inputString)
{
    Match m;
    string HRefPattern = "href\\s*=\\s*(?:[\"'](?<1>[^\"']*)[\"']|(?<1>\\S+))";

    try
    {
        m = Regex.Match(inputString, HRefPattern,
                        RegexOptions.IgnoreCase | RegexOptions.Compiled,
                        TimeSpan.FromSeconds(1));
        while (m.Success)
        {
            Console.WriteLine("Found href " + m.Groups[1] + " at "
                + m.Groups[1].Index);
            m = m.NextMatch();
        }
    }
    catch (RegexMatchTimeoutException)
    {
        Console.WriteLine("The matching operation timed out.");
    }
}
using System;
using System.Reflection;
using System.Text.RegularExpressions;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputString = "My favorite web sites include:</P>" +
                       "<A HREF=\"http://msdn2.microsoft.com\">" +
                       "MSDN Home Page</A></P>" +
                       "<A HREF=\"http://www.microsoft.com\">" +
                       "Microsoft Corporation Home Page</A></P>" +
                       "<A HREF=\"http://blogs.msdn.com/bclteam\">" +
                       ".NET Base Class Library blog</A></P>";
            DumpHRefs(inputString);
        }
    }
}
Pattern Description
href Match the literal string “href”. The match is case-insensitive.
\s* Match zero or more white-space characters.
= Match the equals sign.
\s* Match zero or more white-space characters.
(?:\["'\](?<1>\[^"'\]*)["']|(?<1>\S+)) Match one of the following without assigning the result to a captured group:
– A quotation mark or apostrophe, followed by zero or more occurrences of any character other than a quotation mark or apostrophe, followed by a quotation mark or apostrophe. The group named 1 is included in this pattern.
– One or more non-white-space characters. The group named 1 is included in this pattern.
(?<1>[^"']*) Assign zero or more occurrences of any character other than a quotation mark or apostrophe to the capturing group named 1.
(?<1>\S+) Assign one or more non-white-space characters to the capturing group named 1.

รันจะได้

Found href http://msdn2.microsoft.com at 43
Found href http://www.microsoft.com at 102
Found href http://blogs.msdn.com/bclteam at 176

3.การเปลี่ยน Date Formats

static string MDYToDMY(string input)
{
    try
    {
        return Regex.Replace(input,
                "\\b(?<month>\\d{1,2})/(?<day>\\d{1,2})/(?<year>\\d{2,4})\\b",
                "${day}-${month}-${year}", RegexOptions.None,
                TimeSpan.FromMilliseconds(150));
    }
    catch (RegexMatchTimeoutException)
    {
        return input;
    }
}
using System;
using System.Globalization;
using System.Reflection;
using System.Text.RegularExpressions;

namespace ConsoleApp
{
    class Program
    {
        public static void Main()
        {
            string dateString = DateTime.Today.ToString("d", DateTimeFormatInfo.InvariantInfo);
            string resultString = MDYToDMY(dateString);
            Console.WriteLine("Converted {0} to {1}.", dateString, resultString);
        }
    }
}

รันจะได้

Converted 06/13/2019 to 13-06-2019.

4.การหา protocol และ Port Number จาก URL

using System;
using System.Text.RegularExpressions;

namespace ConsoleApp
{
    class Program
    {
        public static void Main()
        {
            string url = "http://www.contoso.com:8080/letters/readme.html";

            Regex r = new Regex(@"^(?<proto>\w+)://[^/]+?(?<port>:\d+)?/",
                                RegexOptions.None, TimeSpan.FromMilliseconds(150));
            Match m = r.Match(url);
            if (m.Success)
                Console.WriteLine(r.Match(url).Result("${proto}${port}"));
        }
    }
}
// The example displays the following output:
//       http:8080

5.นำ Invalid Characters ออกจาก String

ตัวอย่างนี้จะ strips out all nonalphanumeric characters ด้วย empty string ยกเว้น periods (.), at symbols (@), and hyphens (-)

using System;
using System.Text.RegularExpressions;

public class Example
{
    static string CleanInput(string strIn)
    {
        // Replace invalid characters with empty strings.
        try {
           return Regex.Replace(strIn, @"[^\w\.@-]", "", 
                                RegexOptions.None, TimeSpan.FromSeconds(1.5)); 
        }
        // If we timeout when replacing invalid characters, 
        // we should return Empty.
        catch (RegexMatchTimeoutException) {
           return String.Empty;   
        }
    }
}

ใช้กรองตัวอักษรที่มองไม่เห็นออก ให้เหลือตัวอักษรภาษาอังกฤษ ภาษาไทย และอักขระบางตัว (เพื่อใช้กับ sql query ได้)

[ก-๙] สำหรับภาษาไทยซึ่งมีทั้ง พยัญชนะ สระ ตัวเลขไทยมากมาย ให้เริ่มด้วย “ก” ถึง “๙” จะได้ครบทุกตัวพอดี

query = Regex.Replace(query, @"[^0-9A-Za-zก-๙ ()/.,\-:'_@]", "");
  • 0-9 คือ ตัวเลข
  • A-za-z คือ ตัวอักษรภาษาอังกฤษ
  • ก-๙ คือ ตัวอักษรภาษาไทย
  • ()/.,-‘ คือ ช่องว่าง, วงเล็บ, slash, period, comma, dash, quote, under score
  • @

6.ตรวจสอบ email ว่า format ถูกต้องมั๊ย

private static string DomainMapper(Match match)
{
    // Use IdnMapping class to convert Unicode domain names.
    var idn = new IdnMapping();

    // Pull out and process domain name (throws ArgumentException on invalid)
    var domainName = idn.GetAscii(match.Groups[2].Value);

    return match.Groups[1].Value + domainName;
}
public static bool IsValidEmail(string email)
{
    if (string.IsNullOrWhiteSpace(email))
        return false;

    try
    {
        // Normalize the domain
        email = Regex.Replace(email, @"(@)(.+)$", DomainMapper,
                                RegexOptions.None, TimeSpan.FromMilliseconds(200));

        // Examines the domain part of the email and normalizes it.
    }
    catch (RegexMatchTimeoutException e)
    {
        return false;
    }
    catch (ArgumentException e)
    {
        return false;
    }

    try
    {
        return Regex.IsMatch(email,
            @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
            @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-0-9a-z]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$",
            RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
    }
    catch (RegexMatchTimeoutException)
    {
        return false;
    }
}
using System;
using System.Globalization;
using System.Text.RegularExpressions;

namespace ConsoleApp
{
    class Program
    {
        public static void Main()
        {
            string[] emailAddresses = { "david.jones@proseware.com", "d.j@server1.proseware.com",
"jones@ms1.proseware.com", "j.@server1.proseware.com",
"j@proseware.com9", "js#internal@proseware.com",
"j_9@[129.126.118.1]", "j..s@proseware.com",
"js*@proseware.com", "js@proseware..com",
"js@proseware.com9", "j.s@server1.proseware.com",
"\"j\\\"s\\\"\"@proseware.com", "js@contoso.中国" };

            foreach (var emailAddress in emailAddresses)
            {
                if (IsValidEmail(emailAddress))
                    Console.WriteLine("Valid:   {0}", emailAddress);
                else
                    Console.WriteLine("Invalid: {0}", emailAddress);
            }

            Console.ReadKey();
        }
    }
}

// The example displays the following output:
//       Valid: david.jones@proseware.com
//       Valid: d.j@server1.proseware.com
//       Valid: jones@ms1.proseware.com
//       Invalid: j.@server1.proseware.com
//       Valid: j@proseware.com9
//       Valid: js#internal@proseware.com
//       Valid: j_9@[129.126.118.1]
//       Invalid: j..s@proseware.com
//       Invalid: js*@proseware.com
//       Invalid: js@proseware..com
//       Valid: js@proseware.com9
//       Valid: j.s@server1.proseware.com
//       Valid: "j\"s\""@proseware.com
//       Valid: js@contoso.中国

Validate Email Addresses แบบ Salesforce

bool flag =  Regex.IsMatch(email,
    @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
    @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-0-9a-z]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$",
    RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));

7.extract string ด้วย regex

หา imageWidth, imageHeight จากรูปแบบที่ตายตัวด้วย regex

using System;
using System.Text.RegularExpressions;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string text = "ImageDimension=600x400;ThumbnailDimension=60x40";
            Regex pattern = new Regex(@"ImageDimension=(?<imageWidth>\d+)x(?<imageHeight>\d+);ThumbnailDimension=(?<thumbWidth>\d+)x(?<thumbHeight>\d+)");
            Match match = pattern.Match(text);
            int imageWidth = int.Parse(match.Groups["imageWidth"].Value);
            int imageHeight = int.Parse(match.Groups["imageHeight"].Value);
            int thumbWidth = int.Parse(match.Groups["thumbWidth"].Value);
            int thumbHeight = int.Parse(match.Groups["thumbHeight"].Value);
        }
    }
}

อีกตัวอย่าง ดึงตัวเลขตรงกลางออกมา

string text = "12345-129-888999";
Regex pattern = new Regex(@"\d+-(?<middle>\d+)-\d+");
Match match = pattern.Match(text);
int middle = int.Parse(match.Groups["middle"].Value);
// 129

แต่ถ้ารูปแบบของข้อมูลไม่แน่นอน แต่ prefix และ postfix แน่นอน ใช้ IndexOf() และ Substring() แทนได้

int st = 10; // length of prefix
int end = text.IndexOf("postfix");
string dfpolicyno = text.Substring(st, end - st);

แกะ id ออกมาจาก log (200411.log) แล้วเขียน id ที่ได้ไว้อีกไฟล์ (200411.txt)

using System.Collections;
using System.IO;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string ipFilename = @"200411.log";
            string line;
            ArrayList arr = new ArrayList();
            using (StreamReader ipFile = new StreamReader(ipFilename, Encoding.Default, true))
            {
                while ((line = ipFile.ReadLine()) != null)
                {
                    arr.Add(line);
                    //Console.WriteLine(line);
                }
            }

            string opFilename = @"200411.txt"; // ... [Main] id = '1', ....
            using (StreamWriter w = File.AppendText(opFilename))
            {
                for (int i = 0; i < arr.Count; i++)
                {
                    //w.WriteLine("[{0}]  {1}", i, arr[i]);

                    string text = arr[i].ToString();
                    if (text.Contains("[Main] id ="))
                    {
                        int st = text.IndexOf("id =");
                        string tmp1 = text.Substring(st + 4);

                        int en = tmp1.IndexOf(",");
                        string tmp2 = tmp1.Substring(0, en) + ",";

                        w.Write("{0}", tmp2);
                        //w.WriteLine("{0}", tmp2);
                    }
                }
            }
        }
    }
}

8.ตรวจสอบว่ามีเฉพาะตัวเลขเท่านั้น

  • ^ ตัวเริ่มต้น
  • * zero or more
  • $ ตัวลงท้าย
Regex.IsMatch(idcardno, @"^[0-9]*$");