2017-08-17 126 views
0

我正在研究吉他和絃轉置器,所以從給定的文本文件中,我想識別吉他和絃。例如G#,Ab,F#m等NSRegularExpression不匹配數字符號(#)

我快到了!由於數字符號(哈希標籤),我遇到了一些問題。

例如,您不能在您的正則表達式的數字符號。 NSRegularExpression不會用這個初始化:

let fail: String = "\\b[ABCDEFG](b|#)?\\b" 
let success: String = "\\b[CDEFGAB](b|\\u0023)?\\b" 

我不得不專門提供unicode字符。我可以忍受這一點。

然而,現在我有一個NSRegularExpression對象,它不會匹配這些(銳器=數字符號)時,我有一個文本行,如:

上午了Bb G#ÇDM FE

當它開始處理G#時,與第二個捕獲組相關的清晰度不匹配。 (即NSTextCheckingResult的第二個範圍的位置爲NSNotFound)注意,它適用於Bb ...它匹配'b'

我想知道我需要在這裏做什麼。看起來文檔並沒有涵蓋這個'#'的情況,事實上它有時用於正則表達式(我認爲與評論或某事有關)

有一件事情會很棒,那就是不必看爲#設置unicode標識符,但只是將其用作字符串「#」,然後將其轉換爲與模式很好地匹配。存在這樣的機會,實際上並不是與#關聯的代碼... ...

+0

不是數字符號不同於尖銳符號嗎? –

+0

讓我確切:你不想匹配'Eddd'? 'F#7'怎麼樣?根本原因很明確,但解決方案需要針對這種特定類型的輸入進行量身定製。並嘗試'「\\ b [CDEFGAB] [bm \ u0023]?(?!\\ w)」'。或'\\ b [CDEFGAB] [bm \ u0023]?+(?!\\ w)'。不知道這裏最適合什麼。請檢查。 –

+0

請檢查我的2個解決方案,讓我們知道哪一個最好。 –

回答

2

\bword boundary是一種依賴於上下文的構造。它匹配4個上下文:1)在字符串的開始和字符之間,2)在字符和字符串的結尾之間,3)在字和非字之間以及4)非字和字符字符。

你的正則表達式是寫在最後的正則表達式引擎看到#\b這樣的方式,這意味着一個#如果有後一個字字符將只匹配。

如果您將\b替換爲(?!\w),如果在當前位置右側存在字詞char,則該匹配將失敗,否則它將起作用。

所以,你可以使用

\\b[CDEFGAB](b|\\u0023)?(?!\\w) 

regex demo

詳細

  • \b - 字邊界
  • [CDEFGAB] - 的b#
  • (?!\\w)可選序列 - - 從所述一組
  • (b|\\u0023)?炭負先行失敗的匹配(並導致回溯到前面的模式!爲了避免這種情況,請添加在?之後的以防止回溯到該模式中)如果在當前位置的右側立即存在字符字符。
+0

這看起來不錯。我對Regex仍然很陌生。所以最後一塊難題是,我可以有一個'''G'''',但我也可以有一個是'''G#m7'''的和絃 有很多和絃在那裏,例如,我目前失敗的正則表達式模式是:'''\\ b [CDEFGAB](\\ u0023 | b |♯|♭)?(7 \\(\\ [\\ u0023 \\] 5 ,B9 \\)| maj13 \\ [\\ u0023 \\] 11 | 7 \\(B5,B9 \\)| 7 \\(\\ [\\ u0023 \\] 5,\\ [\\ u0023 \\] 9 \\)| 7 \\(B5,\\ [\\ u0023 \\] 9 \\)| sus2sus4 | maj9 \\ [\\ u0023 \\] 11 | m6add9 | maj7b5 | maj7 \\ [ \\ b「​​'''(由於評論限制,我留下了一堆東西,但你明白了) – horseshoe7

+0

我也應該指出,它與'''Ab'''匹配,但不是'''G#'''鑑於我的語法,這有什麼意義? – horseshoe7

+0

我用不同的變化得到了一些不同的結果。請不要使用音樂術語,他們不會幫助。你有'Ab'和'G#',我看到[正則表達式匹配它們](https://regex101.com/r/284AC6/1)。它在所有情況下都有效嗎?我用'?+(?!\\ w)'替換了'?\\ b'。只要給我一個字符串,說出應該匹配什麼,什麼不應該。 –

0

(我想先說@WiktorStribiżew取得了巨大的幫助,我現在正在寫不會有可能沒有他!我不關心的StackOverflow點和代表,因此,如果您像這個答案,請upvote他的答案。)

這個問題花了很多回合,並有幾個問題正在進行。 最終這個問題應該叫如何在iOS上使用正則表達式來檢測文本文件中的音樂和絃?

答案是(到目前爲止),不是簡單的。

音樂理論

在音樂速成班你有筆記。它們由A->G和一個名爲意外的可選符號組成。 (A音符涉及聽到時音符演奏的聲音的聲頻)一個偶然的可以是一個平坦(表示爲或簡稱爲b)或尖銳(表示爲或簡單地一個#,因爲這些鍵盤更容易打字)。一個偶然的音符以半音爲單位(#)或更低(b)。因此,F#與Gb具有相同的聲學頻率。在鋼琴上,白色琴鍵是沒有意外的音符,黑色琴鍵代表意外的音符。根據音樂片段的某些因素,該作品不會混合意外類型。它可以是整片或銳利的單位。 (取決於作曲的音樂鍵,但在這裏沒有那麼相關。)

就正則表達式而言,你有類似ABCDEFG的東西嗎?確定該筆記。實際上它更復雜。

然後,音樂和絃由根音和它的和絃類型。有超過50種和絃。他們有一個獨特的「文字簽名」。另外,'主要'和絃有一個空的簽名。因此,在僞正則表達式方面你有一個和絃:

[ABCDEFG](b|#)?(...|...|...)?

,你認識的說明(如前)的第一部分,最後可選的是確定和絃類型。不同的類型被省略了,但是可以像m(對於小和絃)或者maj7#5(對於具有增強的第5和絃的第7和絃......不要擔心它)。只要知道有很多字符串常量代表和絃類型)

然後最後,用吉他,你經常會有一個對應的低音音符,它可以在一定程度上改變和絃的音調。您可以通過添加斜線,然後說明,給一般pseudoform表示這樣的:

[ABCDEFG](b|#)?(...|...|...)?(/[ABCDEFG](b|#)?)? // NOT real Regex
real examples: C/F or C#m/G# and so on

,其中最後一部分有斜槓,則同樣的模式來識別音符。

所以把這些放在一起,一般我們希望找到可以採取多種形式和絃,如:

F Gm C#maj7/G# F/C Am A7 A7/F# Bmaj13#11

我希望能找到一個正則表達式來統治他們。我最終編寫了可以工作的代碼,儘管看起來我有點被黑客竊取,無法獲得我想要的結果。

您可以用Swift編寫see this code here。對於我的目的來說,它並不完整,但它會解析一個字符串,返回原始字符串內的Chord結果列表及其文本範圍。從那裏你將不得不完成實施,以滿足您的需求。

已經有iOS上的幾個問題:

  • iOS不處理數字符號(#)以及在所有。當提供正則表達式或匹配文本時,我必須用它的unicode \ u0023替換#,或者最終工作的是用另一個字符(例如'S')替換所有出現的#,然後一旦正則表達式轉換回來這是事。所以我寫的這段代碼經常要在做任何事情之前「清理」模式或輸入文本。

  • 我無法獲得正則表達式來完美分析和絃結構。它並不完全適用於帶有低音音符的Chord,但它可以成功地將Chord與低音音符相匹配,然後我必須分開這兩個組件並分別解析它們,然後重新組合它們。有點巫術,而且我認爲這對於許多人來說如此混亂的東西很糟糕,它也有不同的平臺相關實現。例如,Wiktor向我介紹他編寫的正則表達式模式,以幫助我解決www.regex101.com上的問題,該工作將在該網站上運行,但這些在iOS上不起作用,並且NSRegularExpression會引發錯誤(通常它有一些錯誤使用此#字符)

  • 我的解決方案完全不考慮性能。它只是想讓它工作。