Regular Expressions in Ruby
Well, there are people out there that say that regular expressions or regex or regexp are no extension of a programming language but a language of its own, others might say it is some kind of DSL and so on. The truth about regular expressions that you should know about is that regex are not the same in every single language because there are oddities that only belong to a specific language or group of languages.
Why are they called regular then?
It is not because of something like a regular interval since it does not really look for it, even if we can ask it to return one or more occurrences of a certain string of text. It might be because you expect your favorite language to regularly look for them if you ever pass it a string. You could say it is a more complicated way of comparing stuff than usual, I mean, it is different to variable == 1 or another_variable == :symbol . Here you look for patterns.
What do you mean with patterns?
It would be stuff like /repeated/ or /[0-9]+/ or /[a-z]+/ and many more. Sometimes it is similar to comparing a string directly like in variable == 'repeated' but there also are times when you do not expect something THAT specific but a group of either numbers or characters or even a mix of them. So anything that relatively matches them would also become a valid finding for our matching system called regular expressions and its comparisons. This is something so common in programming that you always get shortcuts to some of these searches like /\d+/ for numbers (actually they are digits) or /\w+/ for characters.
Even though you might want to look for general ways to find matches, sometimes you want to confirm they are something special like people's names. In such case you could do something like /[A-Z]\w+/ to attempt to find them, if people ever cared to capitalize their own names... Sadly, it might also think that some misspelled word like antiMatter is a valid name, even if we meant it to be a term used in physics only. Do not worry, my friends! There is a solution! Use /^[A-Z]\w+/ instead and it will ignore antiMatter for it did not begin with a capital letter, that is what the symbol after the initial backslash does there, to deny there was any match if there is a problem at the beginning.
What if I don't care about capital letters?
In such case, you can do two things to forget about cases in strings.
Either use string.downcase for lowercase or string.upcase for uppercase.
Or just add an lowercase i to the end of the regex like in /\w+ \w+/i
'12.478'.sub(/\d+.\d+/, 'Some Float')
'12.478'.sub(/\d+\.\d+/, 'Some Float')
That is a string that would get substituted or sub'ed by another string, namely 'Some Float' and both are the same, meaning you will get the exact same result, the string to replace the former. Since all floating point numbers (real numbers) are always written with a dot in Ruby, it does not matter if you pick any of those options. The problem with the first choice is that you could also type '12,478' and it would also replace it because a dot . in a regular expression means "any character" in a single slot or caret position. Still, Ruby would not convert it to a real number because it might think that only the first match (12) matters there, but it still can replace it completely with any string of your choice.
If you are looking for temporary replacements, sub is the right method for you! sub! does the same job but it also changes the strings contents till the end of your method or application. For n number of replacements use either gsub or gsub! instead.
Keep in mind that [ and ] are used as a way to group a number of candidates it will be looking for or get replaced later on. | that pipe or pipeline character (or whatever you want to call that weird symbol) means "or" and you can use it to specify that it might accept one pattern option or the other(s). ( and ) are useful if you only care to substitute or manipulate a group of characters that were specified therein. You get matches in general like this...
$1, $2, $3 and so on. Of course if the previous matching variable was the last real match ever found, the rest will be equal to nil, meaning there was nothing else to be looking for.
But how do I verify if it matches without modifying the string?
Right... I should not have forgotten to tell you all about it. Well, that is up to you. You can either use if or unless statements or a case statement.
if (condition)
unless (condition)
case number_or_string_or_symbol
when regex1
# code
when regex2
# code
else
# code
end
There else is valid as a default behavior in case there is no reason to trigger a previous option. It can be used in if, unless and case ... when statements. It got to be the very last option!
By the way, unless is nothing but the negation of if. It is the same as using if !(condition) there. ! means the opposite, most of the time it equals false (or even nil in Ruby). In languages like C or C++, booleans like true and false (or even null or nullptr under some circumstances) are as useful as 1 and 0 respectively to test the true-ish nature of a test. Ruby throws the latter to the garbage can. The reason behind it would be that Integers like 0 and 1 are true by nature in Ruby. It is quite weird indeed.
What do you do if what I am testing is neither a number nor a string from the very beginning?
Right! I knew I had forgotten something as usual. In such situations you can convert it to a string by calling the to_s or to_str or even inspect method. They always return a string! Though there is a catch as always... The former options might return a different string than the latter because they might have employed different formats to process any given object.
If you are dealing with classes, you can either call its name method or just its given name like in Scene_Map or Window_Base. Just never use the === or identity check if you just pick their given names. That also means that you should not use them in case when statements, the result would always be false. In a simple if or unless condition, you can call the is_a?(Name_Your_Class_Or_Module) method to check if that object is a copy of such class (or not).
One last thing... You might also know that =~ can be used for matches as well. Usually you place a string first and a regex later on. It will return a 0 if it is a real match or nil if you fail to find it. In that case you better do exactly what I did in my farewell message below. Then you would get an useful boolean test or true-false check!
Happy Fake ('Captain J.U. Tyler' =~ /captain/i) == 0 Match!
If anybody can ever believe he deserved to be a captain even of a spacecraft simulator.
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9
Maranatha!
The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.
My Original Stories (available in English and Spanish)
List of Compiled Binary Executables I have published...
HiddenChest & Roole
Give me a free copy of your completed game if you include at least 3 of my scripts!
Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Maranatha!
The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.
My Original Stories (available in English and Spanish)
List of Compiled Binary Executables I have published...
HiddenChest & Roole
Give me a free copy of your completed game if you include at least 3 of my scripts!
Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE