2011-03-30 54 views
22

我只是寫一個正則表達式爲使用PHP函數preg_match,包含以下部分:在正則表達式中應該轉義哪些文字字符?

[\w-.] 

要匹配任何單詞字符,以及減號和點。雖然它似乎在preg_match中起作用,但我試圖將它放到名爲Reggy的實用程序中,並且它對「char類中的空範圍」抱怨。試驗和錯誤教導我說,這個問題是由逃逸的減號,把正則表達式爲

[\w\-.] 

由於原來出現在PHP的工作解決了,我很奇怪,爲什麼我應該或不應該逃避減號,並且 - 因爲這個點也是一個PHP中有意義的字符 - 爲什麼我不需要逃避這個點。我使用的實用程序只是愚蠢的,它是用另一個正則表達式方言工作還是我的正則表達式真的不正確,我只是幸運的preg_match讓我擺脫它?

+0

有什麼理由不使用'preg_quote'? – Okonomiyaki3000 2016-09-20 08:34:09

+0

可能不是。但這不是我問這個問題的原因。我試圖學習一些關於正則表達式的新東西,只是使用'preg_quote'會產生完全相反的效果。 :)。我意識到我標記了這個PHP,但我正在尋找可能適用於任何PCRE實現的答案。 – 2016-09-22 22:17:28

+0

我明白了。然後,我可能會建議:https://github.com/php/php-src/blob/a3ca6b09cdf1ed904d3e3a56878c1cf6b1a04d1b/ext/pcre/php_pcre.c – Okonomiyaki3000 2016-09-23 01:34:44

回答

54

在許多正則表達式實現方式中,適用下列規則:

一個字符類中的元字符是:

  • ^(否定)
  • -(範圍)
  • ](的端類)
  • \(逃逸字符)

因此,這些都應該進行轉義。有一些極端情況,但:

  • -需求沒有逃脫,如果放置在一開始,或者類([abc-][-abc])結束。在相當多的正則表達式實現方式中,它也需要時的範圍([a-c-abc])或短手字符類([\w-abc])後直接放置沒有逃逸。這就是你觀察到的
  • ^需求時,它的在課程開始沒有逃脫:[^a]意味着除了a任何字符,並[a^]比賽無論是a^,這等於:[\^a]
  • ]需求沒有逃脫如果它是班上唯一的字符:[]]匹配]
+0

優秀的答案。 – 2011-03-30 09:00:55

+0

非常全面的答案,謝謝。關於'[]]'的一個問題:如果在類中只有一個字符,爲什麼不把它指定爲'\]'? (即不在括號之間) – 2011-03-30 09:01:40

+0

@Pelle「爲什麼不」是另一個問題,不相關的問題。 「不止一種方法去做一件事」是預浸的發明者的座右銘;) – 2011-03-30 09:04:49

4

雖然確實有some characters should be escaped in a regex,但您不是要問關於正則表達式,而是關於字符類。衝刺符號在哪裏是特別的。

,而不是逃避它,你可以把它放在課堂結束,[\w.-]

6
[\w.-] 
  • .通常意味着任何字符,但之間[]沒有特殊的意義
  • []之間-指示範圍除非它被轉義或者第一個或最後一個字符在[]之間
+0

是否'.'真的是在一個字符類的任何字符「,而? (即括號內) – 2011-03-30 09:06:01

+0

@Pelle的確如此。我只是編輯答案。大部分答案都是錯的;-) – 2011-03-30 09:08:27

3

句號在角色等級中失去其元意義。

-在角色類中有特殊的含義。如果它沒有放在方括號的開始或結尾,它必須被轉義。否則它表示一個字符範圍(A-Z)。

但是,您觸發了另一個特例[\w-.]工作,因爲\w不表示單個字符。因爲這樣的PCRE不可能創建一個字符範圍。 \w是一個可能不一致的符號類,因此沒有可用於創建範圍Z till .的結束字符。此外,滿座.將在\w可匹配的第一個ASCII字符a之前。沒有範圍可修復。因此,爲什麼-沒有逃脫你的工作。

0

如果你正在使用PHP的字符,你需要轉義特殊字符的正則表達式,只是使用preg_quote

一個例子來自php.net

<?php 
// In this example, preg_quote($word) is used to keep the 
// asterisks from having special meaning to the regular 
// expression. 

$textbody = "This book is *very* difficult to find."; 
$word = "*very*"; 
$textbody = preg_replace ("/" . preg_quote($word, '/') . "/", 
          "<i>" . $word . "</i>", 
          $textbody); 
?> 
相關問題