[英]Regular expression to find character patterns in free text
我有一個解析文件並將其轉換為XML的應用程序。 應用程序中的處理模塊之一使用正則表達式在自由文本中查找模式。 我正在嘗試確定2種模式,但不是很成功。
模式1:2個字母(不包括元音),后跟2個數字(1-9),然后是2個字母(不包括元音),然后再定義2個字母(例如:WP,NL,GP,EC等)。 每個組之間可能有也可能沒有空格。
例子:
BQ 12 RT WP
BQ12RTGP
BQ12RT GP
模式2:3個字母(az),后跟3個數字(1-9),再定義2個其他字母(例如:WP,NL,GP,EC等)。 每個組之間可能有也可能沒有空格。
例子:
ABC 123 GP
ABC123GP
ABC123 GP
這是一個正則表達式的示例,該正則表達式可查找文本中的特定單詞:
由於您顯然對正則表達式沒有太多的經驗,所以我將在這里做很多解釋。
首先介紹一下背景:正則表達式具有標記和量詞。 令牌是與某物匹配的事物,例如A
是與拉丁大寫字母A匹配的令牌。量詞通過放置在令牌后面並修改該令牌可以連續匹配的頻率來應用於令牌,例如+
是一個量詞,因此前面的令牌至少匹配一次,因此A+
匹配A
, AAAA
或AAAAAAAAA
。
有了這些,就可以對您需要的各種令牌進行一些入門。
我們已經提到的一個:文字字符,例如A
, 1
或其他。 對於需要采用幾個定義值之一的零件,您將需要使用它。 WP
將匹配WP
但僅此而已。
有角色類。 這些都寫在方括號中,並包含各種字符,每個字符都可以匹配。 字符類[AB]
將匹配 A
或 B
。 還可以有字符范圍,因此[AZ]
將匹配ASCII組成部分的任何大寫拉丁字母, [1-9]
將匹配1
到9
任何數字。
然后我們需要一些量詞:
?
導致前面的標記根本不匹配或完全匹配一次,所以AB?
(請記住, ?
僅適用於B
–前一個令牌)將與A
或AB
匹配。 如果可能,它將始終嘗試匹配AB
。
確切的重復可以用{5}
書寫-即,花括號中的數字。 A{2}
將匹配AA
。
好的,我們現在可以開始構建正則表達式了。
首先,我們需要一個包含不帶元音字母的字符類。 [AZ]
顯然會包括它們,所以這還不夠。 但是我們可以使用多個范圍:
[B-DF-HJ-NP-TV-Z]
不漂亮,但是有效。 一些正則表達式引擎為實際的設置操作提供了准備,例如,設置差異以使用字符類並再次排除某些字符,但這現在就足夠了。
但是,我們需要其中兩個,因為有兩個字母:
[B-DF-HJ-NP-TV-Z]{2}
然后有一個空間,也許沒有。 有一個速記字符類,其中包括所有空格(包括空格和制表符): \\s
。 除非有嚴格的要求,否則只能使用空格: \\s?
。 為了增強魯棒性,我們還可以使用\\s*
來匹配任意數量的空格,即使沒有空格也是如此。
然后,我們需要從1
到9
數字: [1-9]
,實際上又需要其中兩個數字: [1-9]{2}
。 到目前為止,我們有以下內容:
[B-DF-HJ-NP-TV-Z]{2}\s*[1-9]{2}
然后我們需要兩個沒有元音的字母,再加上一個空格或不帶空格:
[B-DF-HJ-NP-TV-Z]{2}\s*[1-9]{2}\s*[B-DF-HJ-NP-TV-Z]{2}\s*
在那之后的一部分中,可能有幾個定義的選項之一。 那些可以用豎線|
交替書寫|
。 我們首先需要一個用括號編寫的組,就像在數學中一樣,以限制交替的優先順序(同樣,就像在數學中一樣)。 在其中,我們僅列出所有可能的選項,並用|
分隔|
:
(WP|NL|GP|EC|etc.)
就像字符類一樣,只是它可以匹配多個字符(但仍然只提供一個選項)。
放在一起,我們擁有
[B-DF-HJ-NP-TV-Z]{2}\s*[1-9]{2}\s*[B-DF-HJ-NP-TV-Z]{2}\s*(WP|NL|GP|EC|etc.)
然后有一件事。 即使周圍有字符,這也將匹配,因為大多數引擎中的正則表達式默認情況下將匹配子字符串。 我們從未在任何地方說過,我們上面匹配的內容必須是一個“詞”,可以這么說,這可能是因為我們在某個地方找到了khdgdfgergBQ12RTGPrteryefg
。 為防止某些斷言本身不會匹配任何字符,而是將匹配項綁定到特定位置。 其中一個方便使用的字符是\\b
,它將匹配\\w
字符(實際上完全沒有用的速記字符類,包括字母,數字和下划線)和不是\\w
字符之間的邊界的任何位置\\w
為了快速和骯臟的黑客\\b
是不夠好,以確保我們匹配一個單詞的開頭或結尾,如\\bfoo\\b
會匹配foo
在a foo b
但不是在foobar
。 有些選項更健壯,但編寫時間也更長。 因此,我們可以使用以下內容來滿足某些目的:
\b[B-DF-HJ-NP-TV-Z]{2}\s*[1-9]{2}\s*[B-DF-HJ-NP-TV-Z]{2}\s*(WP|NL|GP|EC|etc.)\b
不過,我現在將第二個模式的構建留給您。 您現在應該已經足夠了解自己動手做。
順便說一句,一個真正好的學習正則表達式的網站是regular-expressions.info 。 事情解釋的方式比我曾經做的,它是同樣有用的學習和參考。
您可以嘗試這樣的事情:
樣式1:
[^\W\d_.AEIOUYaeiouy]{2}\s*\d{2}\s*[^\W\d_.AEIOUYaeiouy]{2}\s*(?:WP|NL|GP|EC)
非常簡單,使用反轉組,因為它比[bcdfghjklmnpqrstvwxzBCDFGHJKLMPQRSTVWXZ]
短,如果您可以使它不區分大小寫,或者知道它總是大寫,則可以使其更短。 要增加2個字母“單詞”,可以在最后一部分(括號內)加上|XX
。
模式2:
[A-Za-z]{3}\s*\d{3}\s*(?:WP|NL|GP|EC)
根據您使用的語言,可能需要更改某些內容。
假設字母必須為大寫:
模式1: [BCDFGHJ-NP-TV-Z]{2}\\s*[1-9]{2}\\s*[BCDFGHJ-NP-TV-Z]{2}\\s*(?:WP|NL|GP|EC)
模式2: [AZ]{3}\\s*[1-9]{3}\\s*(?:WP|NL|GP|EC)
如果要求字符串以非單詞字符或字符串的開頭/結尾作為邊界,則可能還需要考慮在每個字符串的開頭和結尾添加\\b
。
您可以使用此正則表達式來做
^(?!.*[aeiou].*(WP|NL|GP|EC))[a-zA-Z]{2}\s*\d{2}\s*[a-zA-Z]{2}\s*(WP|NL|GP|EC)$
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.