如何在 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")

这是 a way 以匹配您的 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)

或作为 one-liner:

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

注意这个答案随着时间的推移经过了戏剧性的编辑以得出这个最终结论。

通过参考这个网站: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] 将是匹配的数组(因为零索引数组始终是与完整表达式匹配的完整字符串的数组,后续数组将引用反向引用(如果有))。

它写得尽可能精确,但这个表达式仍然 return 误报,尽管可能性很小。

执行此操作的唯一其他方法是使用您感兴趣的每个可能和弦的数组。然后迭代该数组明确搜索每个字符串——这仍然容易出现误报。

这是一个可以修改它的网站:https://regex101.com/r/vW9sJ2/7

NOTE OP 的原始问题是如何将某些字符串组合添加到表达式中,例如 "G,C,D" 或 "A,B,C" (示例由OP)。然而,与我交谈过的音乐家们表示,他们看不出提取和弦组合有何帮助,因为变化如此之多。他们甚至不确定像这样提取和弦会有什么帮助。这让我很好奇 OP 打算用它做什么,我希望他能为我解释(特别是考虑到我的强迫症,看看我花了多少时间,哈哈)。

EDIT 没有 OP 的回复,不确定这是否满足 OP 的需求,我开始怀疑他是否需要更灵活的组合匹配(例如: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})?))?)

和 fiddle 对应的:https://regex101.com/r/vW9sJ2/7