in reply to substitution with regex

Hey dude, not everywhere has perfect climate like Santa Monica! As you may know, negative temps exist at some locations (and are denoted with a leading 'M' in METAR reports).

Here is the skeleton of a solution handling negative temperatures (using the reading from Fairbanks, AK at this time for testing).

(But see also Geo::METAR for an oldie-but-goodie parser for this format, which provides the temp in F in its dump output.)

use strict; use warnings; while ( my $line = <DATA> ) { $line =~ s{ \s (M?\d{2}) / (M?\d{2}) \s } { sprintf ' %d/%d ', convert($1), convert($2) }xeg; print $line; } sub convert { $_[0] =~ s/M/-/r * 9/5 + 32 }; __DATA__ KSMO 181551Z 00000KT 10SM CLR 14/08 A3009 RMK AO2 SLP189 T01440083 PAFA 190153Z 00000KT 5SM -SN BR FEW012 BKN025 OVC070 M07/M08 A2959 RMK + AO2 SLP030 T10671078
Output:
KSMO 181551Z 00000KT 10SM CLR 57/46 A3009 RMK AO2 SLP189 T01440083 PAFA 190153Z 00000KT 5SM -SN BR FEW012 BKN025 OVC070 19/17 A2959 RMK A +O2 SLP030 T10671078

Hope this helps!


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^2: substitution with regex
by drose2211 (Sexton) on Jan 23, 2018 at 03:15 UTC

    Just wondering what exactly is the purpose of the sprintf and %d/%d?

      Hello drose2211,

      The sprintf function applies the formatting specified in the template supplied as its first argument, to produce a string using the remaining arguments. In this case, the template ' %d/%d ' means: print a space, followed by the next argument formatted as an integer, followed by a slash, followed by the next argument formatted as an integer, followed by a space. Without the sprintf function, the code would be longer and less elegant:

      $line =~ s{ \s (M?\d{2}) / (M?\d{2}) \s } { ' ' . int(convert($1)) . '/' . int(convert($2)) . ' ' }xeg +;

      (Perl’s printf and sprintf functions are derived from their equivalents in C. In Perl, there is also print, which does not take a template, but there is no corresponding sprint.)

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      drose2211:   Further to Athanasius's post:   Note also that the  s/// substitution operator needs the  /e modifier to be able to evaluate an arbitrary expression in its replacement block. See  s/PATTERN/REPLACEMENT/ in Regexp Quote-Like Operators in perlop.


      Give a man a fish:  <%-{-{-{-<