簡體   English   中英

紅寶石參數化正則表達式

[英]ruby parametrized regular expression

我有一個類似“ {some | words | are | here}”或“ {another | set | of | words}”的字符串

因此,一般而言,字符串由一個大括號,由管道分隔的單詞和一個大括號組成。

獲取該字符串的所選單詞的最有效方法是什么?

我想做這樣的事情:

@my_string = "{this|is|a|test|case}"
@my_string.get_column(0) # => "this"
@my_string.get_column(2) # => "is"
@my_string.get_column(4) # => "case"

方法get_column應該包含什么?

所以這是我現在喜歡的解決方案:

class String
  def get_column(n)
    self =~ /\A\{(?:\w*\|){#{n}}(\w*)(?:\|\w*)*\}\Z/ && $1
  end
end

我們使用正則表達式來確保字符串格式正確,同時獲取正確的列。

正則表達式的解釋:

  • \\A是字符串的開頭, \\Z是結尾,因此此正則表達式與enitre字符串匹配。
  • 由於花括號具有特殊含義,因此我們將它們用\\{\\}進行轉義,以匹配字符串開頭和結尾處的花括號。
  • 接下來,我們要跳過前n列-我們不在乎它們。
    • 前一列是一些字母,后跟豎線,因此我們使用標准\\w來匹配類似單詞的字符(包括數字和下划線,但為什么不能)和*來匹配任意數量的字母。 豎線有特殊含義,因此我們必須將其轉義為\\| 由於我們希望將其分組,因此將其全部封裝在非捕獲的parens (?:\\w*\\|)?:使它不捕獲)。
    • 現在我們有n列前面的列,因此我們使用regex計數讓正則表達式匹配列模式n次-只需在模式后的花括號中放置一個數字即可。 我們使用標准的字符串替換,因此我們只需輸入{#{n}}即可表示“與先前的模式完全匹配n次。
  • 之后的第一個非跳過列是我們關心的列,因此我們將其放在捕獲括號中: (\\w*)
  • 然后我們跳過其余的列(如果存在): (?:\\|\\w*)*

捕獲列會將其放入$1 ,因此如果正則表達式匹配,我們將返回該值。 如果不是,則返回nil,因為此String沒有第n列。

通常,如果您想在欄目中不只包含單詞(例如"{a phrase or two|don't forget about punctuation!|maybe some longer strings that have\\na newline or two?}" )),那么只需用[^|{}]替換正則表達式中的所有\\w ,這樣您就可以使每一列都包含除大括號或豎線以外的任何內容。


這是我以前的解決方案

class String
  def get_column(n)
    raise "not a column string" unless self =~ /\A\{\w*(?:\|\w*)*\}\Z/
    self[1 .. -2].split('|')[n]
  end
end

我們使用類似的正則表達式來確保String包含一組列或引發錯誤。 然后,我們從前面和后面剝離花括號(使用self[1 .. -2]限制到從第一個字符開始到最后一個倒數第二個子字符串),使用豎線字符(使用.split('|') )分隔列.split('|')創建一個列數組),然后找到第n列(使用[n]使用標准Array查找)。

我只是想過,只要我使用正則表達式來驗證字符串,就最好使用它來捕獲列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM