2013-06-19 46 views
2

我正在使用正則表達式,但也許有點成功,我想補充一些例外,我不希望它影響某些詞。 (見我的previous question for some background ...這解決了給定的問題,現在我需要添加例外)。正則表達式,但忽略某些詞

因此,總的來說,我需要做的是:

  1. 找到像[a-z]_[a-z]的模式,所以像some_var但不_var話。
  2. 忽略在雙引號內找到的那些匹配,所以不是"this_file.jpg"
  3. 忽略給定關鍵字列表中的那些匹配項,所以而不是類似size_t等(我有一個例外列表)。

當我找到合適的比賽,我把它轉換爲駝峯,基本上(some_var - >someVar)並將其成功地在前面回答過的問題。

這是在Ruby中,這是我迄今爲止代碼:

exclusions = ["size_t", "other_t"] 
replacement = text.gsub(/"[^"]+"|_[a-z]/) {|match| (match.length > 2)? match : match[1].upcase } # doesn't do any exclusions from my list, only handles the quoted case. 

我不知所措我那種。我認爲我需要某種負面看法,但我不確定如何去做(不是超級經驗的正則表達式)。

樣品

輸入:

this_var "that_var" size_t 

輸出:

thisVar "that_var" size_t 

也就是說,事物在引號應該是不變,事情在我的排除列表中也應保持不變。任何其他匹配[a-z]_[a-z]的字符串都應該更改。

+0

將是真正有用的,如果你有樣品輸入(S)和輸出(S)完全吻合。 – Dogbert

+1

您可能希望爲此使用至少2個單獨的正則表達式,尤其是對於包含單詞列表的部分。 –

+0

根據排除列表排除數據的一種非常簡單的方法是'%r {exclusions.join(「|」)}',這將生成正則表達式'/ size_t | other_t /'。 – Kashyap

回答

1

您可以使用後視圖(?<=..)來測試您之前有一個字母,並且保留的單詞的長度大於2,因此只需在交替之前添加它們即可。

text.gsub(/"[^"]+"|size_t|(?<=[a-z])_[a-z]/) {|match| (match.length > 2)? match : match[1].upcase } 

注:一個lookbehind(或超前)是隻檢查一個子模式,但不消耗字符的斷言。

請注意,如果需要,"[^"]"可以替換爲"(?:[^"]+|(?<=\\)")+"以允許在雙引號之間使用雙引號。

好的,ruby正則表達式引擎支持atomic groupspossessive quantifiers。你可以重寫這樣你表達更多的演出:

/"[^"]++"|size_t|(?<=[a-z])_[a-z]/ 

/"(?>[^"]++|(?<=\\)")+"|size_t|(?<=[a-z])_[a-z]/ 
2

我不知道Ruby,但在這裏我可以舉一個算法。

匹配的單詞不包圍引號可以實現如下(注:字面正則表達式;做什麼是Ruby的需要,使之成爲可讀的正則表達式):

(?<!")([a-z]+(?:_[a-z]+)*)(?!") 

這將匹配禁止的關鍵字(如例如size_t),但是您可以始終擁有禁止關鍵字列表,並嘗試查看被捕獲的組是否與其中一個禁止關鍵字匹配。從那時起,工作就完成了。

正則表達式演練:

(?<!")   # position where the preceding text is not a double quote 
(    # start group 
    [a-z]+  # one character among 'a' - 'z', one or more times, followed by 
    (?:   # begin non capturing group 
     _  # an underscore, followed by 
     [a-z]+ # one character among 'a' - 'z', one or more times 
    )   # end non capturing group 
    *   # zero or more times, followed by 
(?!")   # a position where what immediately follows is not a double quote 
1

我要問,如果有一個令人信服的理由,做到這一切在一個正則表達式?如果它很重要,我不介意這裏的複雜性。但是如果你認爲你將不得不做更復雜的解析,那麼將它分解成幾個步驟可能是值得的。例如,

  1. 匹配候選詞
  2. 拒絕禁止keywrods
  3. 變換

我的經驗也是,一旦你開始嘗試做更復雜的分析,你可能會考慮更復雜解析器比單純形正則表達式。

+0

具有很多意義。 – nikhil

1

我會做到這一點是這樣的:

input.gsub /"?[a-z]+_[a-z]+"?/ do |match| 
    if match[0] == '"' && match[-1] == '"' || blacklist.include?(match) 
    match 
    else 
    match.gsub(/_[a-z]/) { |match| match[1].upcase } 
    end 
end 

blacklist是單詞的數組,你不想更換。

測試:

input = 'this_var "that_var" size_t' 
blacklist = %w{size_t other_t} 

output = input.gsub /"?[a-z]+_[a-z]+"?/ do |match| 
    if match[0] == '"' && match[-1] == '"' || blacklist.include?(match) 
    match 
    else 
    match.gsub(/_[a-z]/) { |match| match[1].upcase } 
    end 
end 

puts output 

輸出:

thisVar "that_var" size_t