Here's a snippet of some very old in-process code I was writing for time pattern matching where the time was entered as text and needed to be assembled to create an event's start date time. You'll notice that it has a lot of error capture code in it to trap different conditions and report data that couldn't be processed by the trigger.
Edit 2
You'll want to go to somerplace like http://gskinner.com/RegExr/ to sort out the regular expression that you're going to need to use for your pattern. I'd expect you to need something along the lines of ('((MC)|(mc)|(Mc)|(mC))|((MC)|(mc)|(Mc)|(mC))\s|((MC)|(mc)|(Mc)|(mC))\\-|((MC)|(mc)|(Mc)|(mC))\')')
for your pattern. This pattern will capture an "MC" in any combination of cases either by itself or followed by either a space, hyphen or apostrophe. Notice that the hyphen has been escaped, thus the reason for the double backslashes instead of a single one Reference docs show its needed, but unclear from testing at Gskinner. See saved example at http://regexr.com/3a33j. Other corrections have been made since I Initially posted it as well (several missing |
inserted between (mc)
instances and an extra ')
at the end - possible causes of error messages you were receiving.
Note1: you can't use the global flags shown at GSkinner's site with SF's regex pattern matcher class.
Note2: You could also break the above into separate Pattern matcher classes, running them in sequence until one is found, then insert the appropriate substitution.
Once a match is found, you'd then also be able to do your capitalization of the letter that follows. There are numerous ways of approaching this depending on what you're most comfortable working with and your particular situation. Standard string methods toUpper, etc can also be used to do your conversions once you've done your captures. This should suffice to illustrate how this works with regex. See GSkinner's site at the link above for more on regex's look-forward's and look-back capabilities along with the apex docs.
Example code for assembling & formatting a Date-Time from a text entered time string and Date:
string notes;
string strtDt;
string strtTm;
string strtTmM;
string endTm;
string endDtTm;
string strtTmB;
string StrtTmDt;
string sClsDay;
string sClsMnth;
string sClsYear;
Integer ClsDay;
Integer ClsMnth;
Integer ClsYear;
Date ClosDt;
DateTime Strt;
string err;
string err0;
Pattern TimePttrnA = Pattern.compile('((([1])([0-2])|(([0])([1-9])))(\\u003A)(([0-5])([0-9]))(\\s)(([AP])([M])))'); // hh:mm a
Pattern TimePttrnB = Pattern.compile('((([1])([0-2])|(([0])([1-9])))(\\u003A)(([0-5])([0-9])))');
boolean hasMatchA;
boolean hasMatchB;
boolean tst;
for(Opportunity opp : nwEvnt) {
if (opp.Event_Notes__c == null) notes = 'None';
notes = opp.Event_Notes__c;
if(string.isEmpty(opp.Event_Start_Time_Pik__c) == false){
opp.Event_Start_Time_Pik__c.normalizeSpace();
// Do time pattern and match validation
Matcher mA = TimePttrnA.matcher(opp.Event_Start_Time_Pik__c);
hasMatchA = mA.matches();
if(hasMatchA == true){
strtTm = mA.group(0);
}else{
// Do time pattern and match validation again without AM/PM
Matcher mB = TimePttrnB.matcher(opp.Event_Start_Time_Pik__c);
hasMatchB = mB.matches();
if(hasMatchB == true){
strtTmB = mB.group(0);
strtTm = ''+ strtTmB +' PM';
err0= 'invalid opp.Event_Start_Time_Pik__c, added PM to time found';
err = err0;
}else{
strtTm = '00:00 PM';
err0 = 'FATAL ERROR!!! Unable to determine value for opp.Event_Start_Time_Pik__c, set to 00:00 PM';
err = err0;
} // end if(hasMatchB == true)
} // end else if(hasMatchA == true)
} // end if(string.isEmpty(opp.Event_Start_Time_Pik__c) == false)
// Assemble StartTimeDate and Calculate Planned Mins
opp.Event_Notes__c = notes;
try{
nulltst = opp.CloseDate.format();
tst = true;
}catch (Nullpointerexception e){
tst = false;
err0='FatalError!!! Null Pointer Exception Trapped for invalid Close Date';
err = err +', '+ err0;
}
if(tst == true){
ClosDt = opp.CloseDate;
ClsDay = ClosDt.day();
if(ClsDay >= 1 && ClsDay <= 9){
sClsDay = '0' + String.ValueOf(ClsDay);
} else {
sClsDay = String.ValueOf(ClsDay);
}
ClsMnth = ClosDt.month();
if(ClsMnth >=0 && ClsMnth <= 9){
sClsMnth = '0' + String.ValueOf(ClsMnth);
} else {
sClsMnth = String.ValueOf(ClsMnth);
}
ClsYear = ClosDt.year();
sClsYear = String.ValueOf(ClsYear);
strtDt = ''+ sClsMnth + '/' + sClsDay + '/' + sClsYear +'' ;
}else{
strtDt = ''+ sClsMnth + '/' + sClsDay + '/' + sClsYear +' (Possible Data Error: confirm Event Date with Manager) ';
}
if(hasMatchA == false && hasMatchB == false){
StrtTmDt = sClsMnth + '/' + sClsDay + '/' + sClsYear + ' 12:00 PM';
}else{
StrtTmDt = sClsMnth + '/' + sClsDay + '/' + sClsYear + ' ' + strtTm;
}
}
Edit 1A
In your case, here's some more specific code
String N = a.Name;
String N_MCpart;
// Declare a Pattern using the regex pattern I gave you
Pattern myPattern = Pattern.compile('((MC)|(mc)|(Mc)|(mC))|((MC)|(mc)|(Mc)|(mC))\s|((MC)|(mc)|(Mc)|(mC))\\-|((MC)|(mc)|(Mc)|(mC))\')');
// Declare a boolean for when there's a match
boolean hasMatch;
// Do the pattern match on the name string
// Declare a Matcher
Matcher myMatcher = myPattern.match(N);
// Test to see if there's a match
hasMatch = myMatcher.matches();
if(hasMatch == true){
N_MCpart = myMatcher.group(0);
}
Once you have the above, you can manipulate it however you'd like. You'll want to see which "MC" it returned for you to know what to do with it. I'm confident you can figure out what to do with it from here. If there's more than one match, the rest will be in group(1), etc. See the Apex docs for more.