1. 程式人生 > >正則表示式入門(java,python版本)

正則表示式入門(java,python版本)

目錄

  1. 本文目標

  2. 正則表示式到底是什麼

  3. 正則表示式可以用來做什麼

  4. 基本語法

  5. 元字元

  6. 例項

本文目標

快速讓你知道真這個表示式是什麼,對正則表示式的概念有基本的瞭解,並且能夠在不同的程式語言中使用它。

正則表示式到底是什麼

正則表示式,(英語:Regular Expression,在程式碼中常簡寫為regex、regexp或RE),是電腦科學的一個概念。正則表示式使用單個字串來描述、匹配一系列匹配某個句法規則的字串。

注意上文加粗的‘概念’,即用英文來說,叫做concept。顯然,正則表示式是跟程式語言無關的,因此,我們可以使用任何程式語言去實現和使用它。幸運的是,絕大多數程式語言都已經實現了正則表示式,並且提供了相應的類或者API介面,我們可以在程式中直接使用它,而無需去考慮底層是如何實現的。

正則表示式可以用來做什麼

1 驗證字串是否符合指定特徵,比如驗證是否是合法的郵件地址。
2 用來查詢字串,從一個長的文字中查詢符合指定特徵的字串
3 用來替換,比普通的替換更強大
4 等等…

基本語法

一個正則表示式通常被稱為一個模式(pattern),為用來描述或者匹配一系列匹配某個句法規則的字串。
語法很簡單,就是一個“字串”。
例如: "hello Regular Expression" 這個字串:
我們可以用下面語法來篩選出來:
1"hello Regular Expression"
2 "hello*"
3 "hello.+"
4 "hello .+n"
...
這些**描述**篩選出來,這裡我們可以先不用管裡面的"*",".","+"是什麼意思,我們只需知道這個可以作為一個正則表示式的表示形式(基本語法)。

元字元

上面的".","*","+"等字元都是正則表示式中的元字元,關於元字元的講述,可以再新開一篇文章來講解,這裡提供一個正則表示式元字元含義的講解連結,**請認真瀏覽完此頁面再檢視本文章的後面的內容。**
為了避免轉載侵權和防止和諧,這裡提供百度的地址:

字元轉義:

這裡仍然有一個問題:如果我們需要匹配元字元本身,該如何處理?
那麼就需要用到字元轉義符號:'\'。
例如,如果我們需要從"test * test"匹配出 "*"這個符號,
那麼正則表示式就要寫成: "\*",而不是"*",

值得注意的是轉義字元本身:
如果我們需要從"test \ test"匹配出 "\"這個符號,    
那麼正則表示式就要寫成: "\\\\",而不是"\\"。

例項

上面看了這麼多,接下來我們來看看具體的應用例項吧,以加深我們的印象。
下面的例子只提供了Python和Java版本,其它語言類似,可自行參考相應語言的API文件。
  1. 匹配出網頁中的title標籤和其中的內容
    python 程式碼:
#!/usr/bin/python
# coding=utf-8
import re

reg_str = """
    <!DOCTYPE html>
    <html>
    <head>
        <title>我是title</title>
    </head>
    <body>

    </body>
    </html>
"""
reg1 = u"<title>.+</title>"
reg2 = u"<title>.*</title>"
rst1 = re.search(reg1, reg_str)
rst2 = re.search(reg2, reg_str)

print rst1 and rst1.group()
print rst2 and rst2.group()

結果:

我是title
我是title
[Finished in 0.0s]

java 程式碼:

package regular_expression;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Chapter1 {
    public static void main(String []args) {
        String reg_str = "<!DOCTYPE html><html><head>   <title>我是title</title></head><body></body></html>";
        String reg1 = "<title>.+</title>";
        String reg2 = "<title>.*</title>";

        Pattern p1=Pattern.compile(reg1);
        Matcher m1=p1.matcher(reg_str);     

        Pattern p2=Pattern.compile(reg2);
        Matcher m2=p2.matcher(reg_str);     

        if (m1.find()) {
            System.out.println(m1.group());         
        }
        if (m2.find()) {
            System.out.println(m2.group());         
        }
    }
}

結果:

<title>我是title</title>
<title>我是title</title>

結果解釋:

"<title>.+</title>" 
# . 是正則表示式裡面的元字元,檢視元字元的文件可知,.表示 “匹配除換行符以外的任意字元”,因此他會匹配出
# <title></title>之間的任何非換行符。
# +也是正則表示式中的元字元,+表示匹配一次或者多次(即至少匹配一次,同{1,})
# 因此這個正則最終的意思就是 匹配<title></title>之間的任何非換行符,並且至少匹配一次

# 同理 *表示0次或多次,即匹配<title></title>之間的任何非換行符,並且至少匹配0次。

兩個的差別就是:
+不能匹配出 “<title></title>”字串
*可以匹配出 “<title></title>”字串
因為<title></title>之間一個字元也沒有,所以需要*才能匹配。
  1. 統計字串中所有詞的詞性的個數

    Python程式碼:

#!/usr/bin/python
# coding=utf-8
import re

reg_str = """
    詞語1 \q
    詞語2 \w
    詞語3 \ee
    詞語1 \q
    詞語5 \w
    詞語6 \e
    詞語7 \c
"""

reg = u"\\\\[a-z]{1,2}"
rst2 = re.finditer(reg, reg_str)
# 詞性個數
count_map = {}

for m in rst2:
    value = m.group()
    if (count_map.get(value)):
        count_map[value] = count_map[value] + 1
    else:
        count_map[value] = 1

for k,v in count_map.items():
    print '詞性{}的個數為{}'.format(k,v)

結果:

詞性\c的個數為1
詞性\w的個數為2
詞性\e的個數為1
詞性\ee的個數為1
詞性\q的個數為2
[Finished in 0.0s]

java程式碼:

package regular_expression;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.HashMap;
import java.util.Map.Entry;

public class Chapter1 {
    public static void main(String []args) {
        String reg_str = "詞語1 \\q詞語2 \\w詞語3 \\ee詞語1 \\q詞語5 \\w詞語6 \\e詞語7 \\c";

        String reg ="\\\\[a-z]{1,2}";
        Pattern p=Pattern.compile(reg);
        Matcher m=p.matcher(reg_str);       
        // 詞性個數
        HashMap<String, Integer> count_map = new HashMap<String, Integer>();
        String value = "";
        while (m.find()) {
            value = m.group();
            if (count_map.get(value) != null) {
                count_map.put(value, count_map.get(value) + 1);
            } else {
                count_map.put(value,1);
            }
        }
        for (Entry<String, Integer> entry: count_map.entrySet()){
            System.out.println("詞性"+entry.getKey()+"的個數為"+ Integer.toString(entry.getValue())); 
        }       
    }
}

結果:

詞性\q的個數為2
詞性\c的個數為1
詞性\e的個數為1
詞性\w的個數為2
詞性\ee的個數為1

結果解釋:
“\\[a-z]{1,2} 表示匹配 ‘\’符號加上後面的任意1-2個英文小寫字母。
即:\字母 表示詞性的話,那麼這個正則就已經把所有詞的詞性的個數都已經篩選出來。最後再經過詞性的map操作,就把所有詞性的個數計算出來了。

PS:至於為什麼是\\\\,文章前面已經提到。

參考連結: