最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Regex not correctly rejecting invalid music note values - Stack Overflow

programmeradmin1浏览0评论

I am trying to write a regex line for a project which handles music.

It is supposed to make sure the input is a valid note but it doesn't work in all cases, and I can't find any documentation which helps.

Regex h = new Regex(@"(((A|C|D|F|G)?(#?))|(B|E))?\d\d?", 
RegexOptions.IgnoreCase);
Match X = h.Match(Console.ReadLine());

if (X.Success)
{
    Console.WriteLine("VALID");
}
else
{
    Console.WriteLine("INVALID");
}
Console.ReadLine();

It should allow inputs in the format C#1 with the exception of B,E where they must be B1 or E1.

(N.B. 1 is a stand-in for any integer value)

Full valid input list:

C = a,c,d,f,g
B = b,e
1 = any integer value
C1
C#1
B1

Invalid list:

B#1
CCCCC1
C####1
1C
I AM A FISH
C
H (any character not in the defined list)
H#1
H1

Currently the code is incorrectly marking these examples as valid, when they should be invalid:

CCCCCCC1
B#1

I am trying to write a regex line for a project which handles music.

It is supposed to make sure the input is a valid note but it doesn't work in all cases, and I can't find any documentation which helps.

Regex h = new Regex(@"(((A|C|D|F|G)?(#?))|(B|E))?\d\d?", 
RegexOptions.IgnoreCase);
Match X = h.Match(Console.ReadLine());

if (X.Success)
{
    Console.WriteLine("VALID");
}
else
{
    Console.WriteLine("INVALID");
}
Console.ReadLine();

It should allow inputs in the format C#1 with the exception of B,E where they must be B1 or E1.

(N.B. 1 is a stand-in for any integer value)

Full valid input list:

C = a,c,d,f,g
B = b,e
1 = any integer value
C1
C#1
B1

Invalid list:

B#1
CCCCC1
C####1
1C
I AM A FISH
C
H (any character not in the defined list)
H#1
H1

Currently the code is incorrectly marking these examples as valid, when they should be invalid:

CCCCCCC1
B#1
Share Improve this question edited Jan 20 at 10:21 DarkBee 15.7k8 gold badges70 silver badges114 bronze badges asked Jan 20 at 10:08 MIMEC Senchi UNKNOWNMIMEC Senchi UNKNOWN 311 silver badge6 bronze badges 6
  • 1 A regex will match any part of a string. If you need to limit to the whole string, then add ^ and $. So, eg, "B#1" matches on "B" so passes. – fdomn-m Commented Jan 20 at 10:10
  • 2 Off-topic: enharmonically, there's nothing wrong with B#, it's a perfectly valid note. – fdomn-m Commented Jan 20 at 10:17
  • yeah my code just implodes if it appears cause i want to try to make it as user friendly as possible so im shunning it to the abyss same with flats but thats cause i have a thing against flats – MIMEC Senchi UNKNOWN Commented Jan 20 at 10:18
  • Use: @"^(((A|C|D|F|G)?(#?))|(B|E))?\d\d?$" – fdomn-m Commented Jan 20 at 10:24
  • Maybe ^(?:[ACDFG]#?|[BE])\d{0,2}$? A # is only allowed after ACDFG and each letter can be followed with 0, 1 or 2 digits. – Wiktor Stribiżew Commented Jan 20 at 10:28
 |  Show 1 more comment

2 Answers 2

Reset to default 1

I think this pattern can be simplified to just ^([ACDFG]#?|[BE])\d$

It matches all your valid inputs and rejects all your invalid. I have removed the capture groups for clarity, if you needed those just wrap the parentheses in the correct place ()

Your original code had a potential for 2 integers - you can use \d{1,2} to represent that if need be.

Demo: https://regexr.com/8b6vm

Try This

 Regex h = new Regex(@"^([A-D|F-G]#?\d{1,2}|[B|E]\d{1,2})$",RegexOptions.IgnoreCase);
发布评论

评论列表(0)

  1. 暂无评论