Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

$localdir =~ s/\//\\/g;

From my understanding it is changing the forward slash to backward slash. Is it right or wrong? Or the meaning is different for the above line

Replies are listed 'Best First'.
Re: What is the meaning of this line in Perl on linux?
by haukex (Archbishop) on Mar 28, 2022 at 07:56 UTC

    Your understanding of the line is correct. A slightly nicer way to write that to avoid LTS is s{/}{\\}g. But better yet is to use a module like File::Spec or Path::Class for filename manipulation Update: as I showed below.

      > to avoid LTS

      I learned the term slasheritis in (emacs) lisp, which doesn't know raw strings. So since all regexes are strings you have to type \\\\ to escape a single backslash from two levels of interpretation. That's even worse than in Perl.

      The discussion of other programming languages in this WP page looks incomplete to me, because it doesn't always handle the question how to escape the delimiter of a raw string.

      Like this Ruby code

      > 'C:\Foo\Bar.txt'

      won't have any possibility to escape the ' , because \ isn't meta anymore.

      While Go discussed this limitation

      > there is no escape code for a backtick in a raw string.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      Wow! lots of LTS discussion!
      I would prefer: s|/|\\|g; to s{/}{\\}g; but they are equivalent.
      I also like your idea of using a module for the translation.

      However, I am perplexed as to why the OP wants to do that in the first place? I write a lot of Perl on Windows and Windows just isn't DOS anymore. Modern Windows is fine with forward slashes. Better than good code is: "no code". I don't see the need to convert forward slashes to back slashes.

      Having said that, I do have a vague recollection of some command from the Windows command line where I had to use backslash as part of the path to get the command to work. This may have been a legacy issue with ancient MS code. I have never seen such a requirement when using Perl. It could exist, but I haven't come across it yet.

      Anyway, my advice is "don't run a format conversion where it is not necessary".

      Update: Clarification: On the command line, Windows will display back slash, but that does not mean that you have to use them:

      C:\Users\xxx\Documents\PerlProjects> cd C:/Users C:\Users>
      A Perl program is not getting what Windows displays for its command line.

        Modern Windows is fine with forward slashes

        Not quite, as described in more detail at: Re^4: windows perl and paths

        BTW, I'm surprised nobody suggested using the tr transliteration operator: $localdir =~ tr{/}{\\};

        > Modern Windows is fine with forward slashes

        To be pedantic, note that all Win32 API functions have always treated forward slashes and back slashes equivalently in file path arguments ... and the Win32 API was introduced with Windows NT/Windows 95 in the 1990s ... so you don't really need an especially "modern" version of Windows. :)

        I don't see the need to convert forward slashes to back slashes.

        With all the talk of APIs in this subthread I'd just like to remind everyone of the probably hundreds if not thousands of nodes on this site of people doing things like split /\\/, /\\([^\\]+)$/, and many more variations of hardcoded separators. Extrapolate that out to all the other programming languages and I think there is tons of non-portable code out there, therefore I personally always use the respective OSs' native format.

      There is changing the Two forward slashes to two backward slashes

      $localdir =~ s/\\\///g;

      The above line can i use for changing the backward slashes to forward slashes

        Hopefully this makes it clearer:

        # delimiters # | | | # v v v $localdir =~ s/\//\\/g; # ^^ ^^ # | | # search part replacement

        But for regexes, I would recommend using what I suggested:

        $localdir =~ s{\\}{/}g;

        But as I said, using a module for this is even better:

        use warnings; use strict; use Path::Class qw/foreign_file foreign_dir/; my $file = foreign_file('Win32', "..\\Hello\\World.txt"); print $file->as_foreign('Unix'), "\n"; # prints "../Hello/World.txt"
        A reply falls below the community's threshold of quality. You may see it by logging in.

        No. The above line is a syntax error and Perl tells you so.

        Maybe you want to learn about Perl quoting rules for strings? The backslash \ is special in Perl strings and is used to mark the next character as exempt from the quoting rules. See Quote-and-Quote-like-Operators, especially the section about Escape Sequences. There it explains why you need to write \\ when you want to match a single \ in a regular expression.

Re: What is the meaning of this line in Perl on linux?
by hippo (Archbishop) on Mar 28, 2022 at 10:38 UTC

    Why not try it and see?

    $ echo '/x//b/c/' | perl -pe 's/\//\\/g' \x\\b\c\

    🦛