2017-08-17 51 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会引发错误(通常它有一些错误使用此#字符)

  • 我的解决方案完全不考虑性能。它只是想让它工作。