2017-01-09 24 views
3

我有一個本地化的字符串,看起來在英語中是這樣的:正則表達式來提取若干步驟


5英里(S)
5,252步驟(S)

我的應用程序是以左向右和從右向左語言進行本地化的,因此我不想對step(s)的排序或關於數字格式的假設(例如5,252可以是5.2 52取決於用戶區域設置)。所以,我需要考慮的可能性,可以加入

步驟(S)5.252

以及什麼是上面的事。

其他一些注意事項

  • 我所知道的是,如果Step(s)線就在那裏,這將是自己的行(因此在我的正則表達式我需要在繩子的兩端。\ n)
  • 不能保證Mile(s)信息將在字符串中可言,更談不上是否會之前或之後Step(s)

這裏是我的方式提取嘗試:

NSString *patternString = [NSString stringWithFormat:@"\\n(([0-9,\\.]*)\s*%@|%@\s*([0-9,\\.]*))\\n", 
    NSLocalizedString(@"Step(s)",nil), NSLocalizedString(@"Step(s)",nil)]; 

似乎有兩個問題:

  • Xcode是指示Unknown escape sequence '\s'在圖案串的第二\s上述
  • 沒有球賽被發現甚至對於像以下字符串:

0.2英里(S)
1482步驟(一個或多個)

理想情況下,我會以本地化友好的方式從該字符串中提取1,482。我應該如何修改我的正則表達式?

+0

我想你也想提取里程。但要澄清,你*只*想要的步驟? – sweaver2112

+0

從右到左在這裏是錯誤的術語。在RTL語言中,數據顯示*的方式是數字在單詞的右側,但是**字符的順序仍然是相同的**:'\ d + \ w +'對於希伯來語將起作用。語言環境仍然可能會優先選擇單詞後面的數字。一個例子是貨幣:[20美元對20美元](http://english.stackexchange.com/a/11341/220) – Kobi

回答

0

你的正則表達式是接近,雖然在Obj-C你需要雙擊逃脫\s(s)

^(([0-9,.]*)\\s*%@|%@\\s*([0-9,.]*))$ 

在你NSLocalizedString,你可能還需要對括號進行轉義封閉(s)

NSString *patternString = [NSString stringWithFormat:@"^(([\\d,.]+)\\s%@|%@\\s([\\d,.]+))$", 
     NSLocalizedString(@"Step\\(s\\)",nil), NSLocalizedString(@"Step\\(s\\)",nil)]; 

如果不亞太經社會e (s)那麼正則表達式引擎可能會將其解釋爲捕獲組。在NSLog

看你能看到什麼模式實際上倒像是:

NSLog(@"patternString: %@", patternString); 

輸出:

patternString: ^(([\d,.]+)\sStep\(s\)|Step\(s\)\s([\d,.]+))$ 
1

至於正則表達式,也許這種方法可能會奏效 - 它只是號碼中的各個對聯相匹配(與命名組)的序列中,假設第一是英里,第二個是步驟。在.,形式小數可選:

(?<miles>\d+(?:[.,]\d+)?).*?(?<steps>\d+(?:[.,]\d+)?) 

(我想應該是\\s) - 我不是一個IOS的傢伙,但如果你可以使用正則表達式字面這將是方式更具有可讀性。

regular expression demo

+0

感謝您的建議。我應該在上面詳細說明我的答案,以表明我不想承擔裏面的「Miles」部分。 – helloB

+0

他的解決方案沒有提到「英里數」。 '(? ...)'只是您可以參考的簡單提取組的名稱。它不匹配任何東西。 – sapanoia

0

既然你提到的Mile(s)部分可能無法在字符串,我假設它與正則表達式無關。正如我從這個問題所理解的那樣,你只需要捕獲步驟的數量,而不需要其他任何東西。在此基礎上,這裏是你現有的正則表達式的修改版本:

NSString *patternString = 
    [NSString stringWithFormat:@"^(?:([0-9,.]*)\\s*%@|%@\\s*([0-9,.]*))$", 
    NSLocalizedString(@"Step\\(s\\)",nil), NSLocalizedString(@"Step\\(s\\)",nil)]; 

演示: https://www.regex101.com/r/Q6ff1b/1

這是基於以下提示/修改:

  1. 使用m(= UREGEX_MULTILINE )標誌選項創建正則表達式來指定^$匹配每行的開始和結束。這比使用\n更復雜,因爲它也會處理可能不存在的字符串的開始和結束。見here
  2. 始終使用雙反斜線(\\)的正則表達式轉義 - 否則的NSString會解釋單反斜線是轉義下一個字符,它得到的正則表達式之前將其轉換。
  3. 字母括號需要轉義 - 例如Step\\(s\\)而不是Step(s)
  4. 字符類中的字符(即[]方括號內的任何字符)不需要轉義 - 所以它將是.而不是\\.--後者。
  5. 如果您使用(x|y|...)作爲選擇,並且不需要它爲捕獲組,請在第一個括號後面使用?:以確保它不會被捕獲 - 即(?:x|y|...)
1

首先我想問 - 爲什麼Mile(s)在所有問題中提到?

而現在我的兩位 - 你可以簡單地使用正前瞻:

^(?=.*Step\(s\))[^\d]*(\d+(?:[.,]\d+)?) 

它確保預期的詞存在就行了,然後捕獲用戶的數量,允許本地化,可選,小數分隔符和小數點。這樣,數字在「單詞」之前還是之後並不重要。

它不走「字」進去的國產化,但你似乎已經自行處理;)

See it here at regex101