On Jul 22, 2009, at 6:18 PM, spox wrote: > On Wednesday 22 July 2009 14:58:47 Stephen Beard wrote: >> Hello, >> >> I am new to ruby and had a question about parsing text. >> >> I am trying to parse out the first IP address from a string. I have a >> working solution, but it seems like a rather round about way to do >> it. >> This is my current method: >> >> str = " inet addr:192.168.1.118 Bcast:192.168.1.255 >> Mask:255.255.255.0" >> ipAddr = ((str.split(':'))[1].split)[0] >> >> Is there a better way to do this? Thanks in advance. > > regexp: > str.scan(/addr:([^\s]+)/)[0][0] > > string math: > str.slice(str.index(':')+1, str.index(' B')-str.index(':')-2) > irb> str = " inet addr:192.168.1.118 Bcast:192.168.1.255 Mask:255.255.255.0" => " inet addr:192.168.1.118 Bcast:192.168.1.255 Mask: 255.255.255.0" irb> re = /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/ => /\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/ irb> str.scan(re) => ["192.168.1.118", "192.168.1.255", "255.255.255.0"] So the first one is just: str.scan(re).first or str.scan(re)[0] If you want to be tighter about matching valid IP addresses, look at the alternate regexps about halfway down this page: http://www.regular-expressions.info/examples.html or the grand-daddy one with explanation of all the details: http://www.regular-expressions.info/regexbuddy/ipaccuratecapture.html If you include the capturing groups, the String#scan keeps them: irb> re1 = /\b(?:\d{1,3}\.){3}\d{1,3}\b/ => /\b(?:\d{1,3}\.){3}\d{1,3}\b/ irb> re2 = /\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) \.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) \.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) \.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/x => /\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) \.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) \.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) \.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/x irb> re3 = /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3} (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/x => /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3} (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/x irb> [re, re1, re2, re3].each do |r| ?> puts '-'*30 irb> puts r irb> p str.scan(r) irb> end; nil ------------------------------ (?-mix:\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b) ["192.168.1.118", "192.168.1.255", "255.255.255.0"] ------------------------------ (?-mix:\b(?:\d{1,3}\.){3}\d{1,3}\b) ["192.168.1.118", "192.168.1.255", "255.255.255.0"] ------------------------------ (?x-mi:\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) \.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) \.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) \.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b) [["192", "168", "1", "118"], ["192", "168", "1", "255"], ["255", "255", "255", "0"]] ------------------------------ (?x-mi:\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3} (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b) ["192.168.1.118", "192.168.1.255", "255.255.255.0"] => nil -Rob Rob Biedenharn http://agileconsultingllc.com Rob / AgileConsultingLLC.com