如何在preg_match_all中制作模式字符串


How to make pattern string in preg_match_all

如何为preg_match_all()函数制作一个模式字符串如果我有多个字符串匹配,如"G,C,D" &"A,B,C","E,C,D"

当前我的字符串是

 $str = "/(?<='b)([CDEFGAB](?:b|bb|m)*(?:#|##|sus|maj|min|aug)*['d'/]*(?:[CDEFGAB](?:b|bb‌​|m)*(?:#|##|sus|maj|min|aug)*['d'/]*)*)(?='s|$|(<.*>))(?! 'w)/"
    preg_match_all($str,$lyrics , $output_array);

我想在$str字符串中添加这些组合("G,C,D" & "A,B,C" & "E,C,D")

说明这个答案经过了时间的大量修改,才得出了这个最终结论。

通过参考这个站点:http://www.all-guitar-chords.com/我想出了这个正则表达式:

'b(?:G,C,D|A,B,C|E,C,D)|(?:[ABCDEFG](?:#|b)?)(?:'/[ABCDEFG]b)?(?:(?:(?:maj|min|sus|add|aug|dim)(?:'d{0,2}(?:#'d{1,2}|sus'd)?)?)|(?:m'd{0,2}(?:(?:maj|add|#)'d{0,2})?)|(?:-?'d{0,2}(?:'([^)]*')|#'d{1,2})?))?)

<?php preg_match_all( '`' . $reg_exp . '`', $str, $matches ); ?>

我的最终表达式不捕获任何反向引用。因此,$matches[0]将是一个匹配数组(因为零索引数组始终是一个匹配完整表达式的完整字符串数组,后续数组将引用反向引用,如果有的话)。

已经尽可能精确地编写了,但是这个表达式仍然可能返回假阳性,尽管这种可能性很小。

唯一的另一种方法是使用您感兴趣的每个可能的和弦的数组。然后迭代该数组,显式地搜索每个字符串——这仍然容易出现误报。

这里有一个网站可以修补它:https://regex101.com/r/vW9sJ2/7

OP最初的问题是如何在表达式中添加某些字符串组合,如"G,C,D"或"A,B,C"(OP给出的例子)。然而,与我交谈过的音乐家说,他们不明白提取和弦组合有什么帮助,因为有这么多的变化。他们甚至不确定提取这样的和弦会有什么帮助。这让我很好奇OP打算用这个做什么,我希望他能给我解释一下(特别是看到我花了多少时间在这个上面,因为我有强迫症,哈哈)。

编辑没有回复OP,不确定这是否满足OPs的需要,我已经开始怀疑他是否需要一个更灵活的组合匹配(例如:G,C,D)。所以我修改了表达式来处理:

'b(?:[ABCDEFG],[ABCDEFG],[ABCDEFG])'b|(?:[ABCDEFG](?:#|b)?)(?:'/[ABCDEFG]b)?(?:(?:(?:maj|min|sus|add|aug|dim)(?:'d{0,2}(?:#'d{1,2}|sus'd)?)?)|(?:m'd{0,2}(?:(?:maj|add|#)'d{0,2})?)|(?:-?'d{0,2}(?:'([^)]*')|#'d{1,2})?))?)

和小提琴:https://regex101.com/r/vW9sJ2/7

这是一个匹配你的G,C,D类字符串的方法:

'b
(?:(?:[CDEFGAB]
 (?:b|bb|m)*
 (?:'#|'#'#|sus|maj|min|aug)*
 ['d'/]*
 (?:[CDEFGAB]
  (?:b|bb‌​|m)*
  (?:'#|'#'#|sus|maj|min|aug)*
  ['d'/]*
 )*
),?)+
(?='s|$|(?:<.*>))
(?![[:blank:]]'w)

或者作为一行字:

'b(?:(?:[CDEFGAB](?:b|bb|m)*(?:'#|'#'#|sus|maj|min|aug)*['d'/]*(?:[CDEFGAB](?:b|bb‌​|m)*(?:'#|'#'#|sus|maj|min|aug)*['d'/]*)*),?)+(?='s|$|(?:<.*>))(?![[:blank:]]'w)