[Question]
  [
In this challenge you will take a an ascii art image of a highway like so
```
 |   |   |  |  |  |
 |       |  |     |
 |   |   |  |  |  |
 |       |  |     |
 |   |   |  |  |  |
 |       |  |     |
 |   |   |  |  |  |
```
And you need to put rain across its lanes like so
```
 |\\\|\\\|  |\\|\\|
 |\\\\\\\|  |\\\\\|
 |\\\|\\\|  |\\|\\|
 |\\\\\\\|  |\\\\\|
 |\\\|\\\|  |\\|\\|
 |\\\\\\\|  |\\\\\|
 |\\\|\\\|  |\\|\\|
```
---
A highway will be defined as an ascii art string containing only the characters `|`,  and newlines. All rows of the image will have exactly the same number of characters. Every column will be one of the following
* **Empty space**, all spaces
* **A line**, all `|`
* **A lane divider**, alternating `|` and space
Furthermore there will always be a line before and after every lane divider. So
```
|    |   | |   |
|          |   |
|    |   | |   |
```
would be valid but
```
|     |     |
|  |  |      
|     |     |
```
would not be since there is no line after the last lane divider.
And a lane divider will never be exactly next to a line.
So
```
||   |
|    |
||   |
```
Is invalid but
```
|   ||  ||
|     | ||
|   ||  ||
|     | ||
|   ||  ||
```
is fine.
Additionally a highway must be at least two rows high and one column wide.
## Task
Your job is to write a program or function that takes a valid highway (as a string or list of lines) as input and outputs the highway with rain across its lanes.
To put rain across a highway's lanes you must replace all space characters that appear between two consecutive lines, where those lines have at least one lane divider between them, with `\`s. And leave all other characters the same.
So in the following diagram:
```
A   B   C   1   2  D
|   |   |       |  |
|   |   |   |      |
|   |   |       |  |
|   |   |   |      |
```
No rain should be put between `A` and `B` or `B` and `C` since there are no lane dividers between them, but rain should be put between `C` and `D` since lane dividers `1` and `2` are between them.
You may output an additional trailing newline, or add/remove trailing spaces from all lines equally if you wish.
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") so answers will be scored in bytes with fewer bytes being better.
## Test cases
Simple case
```
 |   |   |  |  |  |
 |       |  |     |
 |   |   |  |  |  |
 |       |  |     |
 |   |   |  |  |  |
 |       |  |     |
 |   |   |  |  |  |
```
---
```
 |\\\|\\\|  |\\|\\|
 |\\\\\\\|  |\\\\\|
 |\\\|\\\|  |\\|\\|
 |\\\\\\\|  |\\\\\|
 |\\\|\\\|  |\\|\\|
 |\\\\\\\|  |\\\\\|
 |\\\|\\\|  |\\|\\|
```
---
Extra line
```
|    |   | |   |
|          |   |
|    |   | |   |
```
---
```
|\\\\|\\\|\|   |
|\\\\\\\\\\|   |
|\\\\|\\\|\|   |
```
---
Unsynced lane dividers
```
   |    |      |
   |        |  |
   |    |      |
   |        |  |
   |    |      |
```
---
```
   |\\\\|\\\\\\|
   |\\\\\\\\|\\|
   |\\\\|\\\\\\|
   |\\\\\\\\|\\|
   |\\\\|\\\\\\|
```
---
Empty road
```
|   |   |       |  |
|   |   |   |      |
|   |   |       |  |
|   |   |   |      |
```
---
```
|   |   |\\\\\\\|\\|
|   |   |\\\|\\\\\\|
|   |   |\\\\\\\|\\|
|   |   |\\\|\\\\\\|
```
---
False roads (suggested by [Arnauld](https://codegolf.stackexchange.com/u/58563))
```
|   | | |   |
|   |   |   |
|   | | |   |
|   |   |   |
```
---
```
|   |\|\|   |
|   |\\\|   |
|   |\|\|   |
|   |\\\|   |
```
---
Hard lane divider
```
|  |  |  |  |
|     |     |
|  |  |  |  |
|     |     |
```
---
```
|\\|\\|\\|\\|
|\\\\\|\\\\\|
|\\|\\|\\|\\|
|\\\\\|\\\\\|
```
---
Adjacent lane dividers
```
|   ||  ||
|     | ||
|   ||  ||
|     | ||
|   ||  ||
```
---
```
|\\\||\\||
|\\\\\|\||
|\\\||\\||
|\\\\\|\||
|\\\||\\||
```
---
No lanes
```
|    |     |  |
|    |     |  |
|    |     |  |
```
---
```
|    |     |  |
|    |     |  |
|    |     |  |
```
---
One line
```
       |
       |
       |
```
---
```
       |
       |
       |
```
---
No lines
```
    
    
    
```
---
```
    
    
    
```
  
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~18~~ 16 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
ZḢ”\E?€ṣ”|»Ṁ$€K»
```
A monadic Link accepting a list of lines, each of which is a list of characters, which yields another, similar list.
**[Try it online!](https://tio.run/##y0rNyan8/z/q4Y5FjxrmxrjaP2pa83DnYiC75tDuhzsbVIB870O7/z/cveVwe@T//zUKChCkUAOia7gQAiASRYBYFQA "Jelly – Try It Online")** Or see the [test-suite](https://tio.run/##y0rNyan8/z/q4Y5FjxrmxrjaP2pa83DnYiC75tDuhzsbVIB870O7/x@dDBadc2ib3qFtQNmHu7ccbo881gWUzkIS/v9foUZBAYahiAvMV4CLKcDFaKxOj6tGAS4KJrlgOmHCmCr0uKACMFtquBBsmANIVwFxSw2SwhqY9WgSNSSohJmK7L0aFL/hkgPrRAqrGgWEc2vwykHtBMkgpKBMvKJI0YFsMB4@OC7gIYzGgEjiJAA "Jelly – Try It Online").
### How?
```
ZḢ”\E?€ṣ”|»Ṁ$€K» - Link: list of lists of characters (i.e. rows of text)
Z                - transpose - i.e. columns (each being: all spaces; all pipes; or a mix) 
      €          - for each (column):
     ?           -   if...
    E            -   ...condition: all equal? - i.e. if not dashed
 Ḣ               -   ...then: head - i.e. the unique character
  ”\             -   ...else: literal '\' character
        ”|       - literal '|' character
       ṣ         - split at - i.e. highway chunks now contain spaces and '\' characters
             €   - for each (chunk):
            $    -   last two links as a monad:
           Ṁ     -     maximum - N.B. '\' > ' '
          »      -     maximum (vectorises across the chunk)
                 -   - i.e highway chunks become all '\', others remain as is
              K  - join with space characters
               » - maximum (vectorises across the rows)
                 -   - N.B. '|' > ' ' so the solid lines are not replaced by spaces; and
                 -          '|' > '\' so the dashed lines are not replaced with rain.
```
[Answer]
# JavaScript (ES6), ~~118 ... 105~~ 103 bytes
I/O format: matrix of characters.
```
a=>a.map(r=>r.map((c,i)=>(a[k=0][i]+a[1][i]<'||'?r:r=a.some(r=>r[a[k^=1].indexOf(c,i+1)]<c))/c?'\\':c))
```
[Try it online!](https://tio.run/##vVPLboMwELzzFatcbIvULdcoJp/QDzCuZBGoSBM7MlXVw/47DQRoeUlEssrFq50Z73hsTvpLl6krrp9Pxh6zKheVFrHmF32lTsSuKWi6LZiIqZYf4kXJQoVaRvW6J4jk4HZOaF7aS9ZI5I32JiLFC3PMvl/zWh1GTO1Txp7TA0kSsruVVWpNac8ZP9t3mlMZAEjO@QYQ7h9CW@JGbQco9ijOoP@nDRS7BwUiBsdPtjCUEMbaKjGEQQjNGgQLx0XoN8bRzM5QRxhDA5UPL@2eXRKD8/fdaXCeVL7SxD9TcRrbiLIEr1b7sz3/AnDh@lfwPVmb/V0Qfm9v1F/D95ZaPWZuzqT5OPMBj9UP "JavaScript (Node.js) – Try It Online")
### How?
To detect lines, we test whether the first and the second row both contain a `|` at a given position \$i\$:
```
a[0][i] + a[1][i] < '||'  // true if it's not a line
```
When a line is detected:
* We know for sure that the character \$c\$ at the same position in the current row is a `|`, because lines are guaranteed to go all the way from top to bottom. So we can now use \$c\$ instead of `'|'`.
* We update the flag \$r\$ which is set to \$1\$ when we're located on a road with a lane divider.
We update \$r\$ by testing if, for some \$n\$, the next `|` (starting from \$i+1\$) in either the first or the second row (depending on the parity of \$n\$) is facing a space in the \$n\$-th row:
```
r = a.some(r => r[a[k ^= 1].indexOf(c, i + 1)] < c  // starting with k = 0
```
Finally, we must replace \$c\$ with a `\` if \$c\$ is a space and \$r=1\$. Because a space is the only road character that is coerced to \$0\$, we can simply do:
```
r / c
```
The only truthy value is given by `1/' '` (\$+\infty\$). Something like `1/'|'` would result in `NaN`, and so does `0/' '` (\$0/0\$).
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 20 bytes
```
₆F€SøíJ„ \S„\|N_èì`:
```
[Try it online!](https://tio.run/##yy9OTMpM/V/z/1FTm9ujpjXBh3ccXuv1qGGeQkwwkIyp8Ys/vOLwmgSr/7WHdv9XqFFQgGEo4gLzFeBiCnAx2qoDAA "05AB1E – Try It Online")
```
₆F                    # repeat the following 36 times:
  €SøíJ               #  rotate 90 degrees
       „ \S           #  character array [' ', '\']
           „\|        #  string "\|"
              N       #  0-based iteration count
               _      #  logical not: 0 => 1, anything else => 0
                è     #  use that to index in the string "\|"
                 ì    #  prepend (first loop: ["| ", "|\"], then ["\ ", "\\"])
                  `:  #  recursive replace ("| " => "|\" or "\ " => "\\")
```
[Answer]
# [Perl 5](https://www.perl.org/) `-p`, ~~52~~ 51 bytes
```
/
/;s/(\S(.{@{-}})|\\)\K | (?=(?2)\S|\\)/\\/s&&redo
```
Replace space character with a backslash if there is a non-space character above or below it or a backslash on the right or the left of it. And redo while no more space can be replaced.
One byte saved diverting recursive regex thanks to Grimmy.
[Try it online!](https://tio.run/##K0gtyjH9/1@fS9@6WF8jJlhDr9qhWre2VrMmJkYzxluhRkHD3lbD3kgzJhgkoh8To1@splaUmpL//z9QUgGGoYgLzFeAiynAxWisjqtGAS4IJrlgGmHCmCq4oHyYHTVcCDbMetJVcCG5DqEMWRCulHiVXDUovq1RQFhZg1cOYhxIAiEDZeIV5ULyVA1K6OHgcykgBREag@tffkFJZn5e8X9dA4MCAA "Perl 5 – Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), ~~198~~ ~~196~~ ~~186~~ 159 bytes
```
def g(x):
 for _ in x[0]:x=[''.join([q,'\\'][q<'!'and(x[a-1][b]>'['or'\\'in r[b-1]+r[-~b%len(r)])]for(b,q)in enumerate(x[a]))for(a,r)in enumerate(x)]
 return x
```
[Try it online!](https://tio.run/##hZDRCoJQDIbvfYp1ETsji6I7qV5kHuJIRzPsqMvAQHp1O2IFedNgbHz/9jNWPZpz6bZ9f7IpZKqlKIC0FDhC7qDltY7aPSOuLmXuFNchxjFqrnc4Q@NOqmWz3GhO9AEZSxlUvyeceLoQXj6TeWGdEtKkva1Kwpr8gHX3qxXT2MFAEw2SCWUikQ5AbHMXf0lv9ogIHcA3YawdBD@4G/kU/5v27kEluWuUoXfzqRi79wMyZVa3qshHRj76Fw "Python 3 – Try It Online")
## Explanation
This implements a simple automaton. At every step a space is replaced with an `\` iff one of the following is true
* There is a `|` or `\` above it (indexing wraps around)
* There is `\` to the left or right of it.
This means that rain starts at the gaps in the lane dividers and spreads until it hits `|`s.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~112~~ ~~109~~ 107 bytes
```
lambda r:reduce(lambda r,c:[''.join(l[::-1]).replace(c+' ',c+'\\')for l in zip(*r)],r'|\|\\\\:'*len(`r`),r)
```
[Try it online!](https://tio.run/##jY7BCsIwEETv/YrBS5IaC3qM9EuaQmubYiSmYakHJf8ea4sexIMLs8vum4UJ9@k8@kMaSp1cez31LUiR6W@d4e9ddqpirLiM1nNXKbXb16IgE1w7m7otA5Nz15qJYSQ4WI@HDTwnUUtiUUc9l2K5M5431AhJIhFKVBk2iMBHWGfERn6juLJf6M@v@pgt8aw3r4QDJ6EyBLJ@Wo7pCQ "Python 2 – Try It Online")
## [Python 3.8 (pre-release)](https://docs.python.org/3.8/), 109 bytes
*Thanks to Kevin Cruijssen for this version!*
```
lambda r:[(r:=[''.join(l[::-1]).replace(c+' ',c+'\\')for l in zip(*r)])for c in r'|\|\\\\:'*len(repr(r))][-1]
```
[Try it online!](https://tio.run/##jY7BCsIwEETv/Yqll01qLYgXifRLkhxqTTESk7D0ouTfY9qCB/Hgwu7CPGaY@JxvwR9PkfLUq@yGx@U6AAnJSPQSsbsH65mTQuwPmndkohtGw8YdArblKoV8CgQOrIeXjawhrldlXBTCpJIqI7BxxrPiJ0aca1niMkEPsoIaEsBnYfsJ6vYbpY39Qn@69Lla21pvlnpT6SIqiGT9zBaR5zc "Python 3.8 (pre-release) – Try It Online")
Port of [my 05AB1E answer](https://codegolf.stackexchange.com/a/200841/6484).
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 25 bytes
```
n⁶Zṣ1€oFẸḤƊ$€j1€W$Zị“|\ ”
```
[Try it online!](https://tio.run/##y0rNyan8/z/vUeO2qIc7Fxs@alqT7/Zw146HO5Yc61IB8rJAQuEqUQ93dz9qmFMTo/CoYe7/h7u3HG6P/P@/RgEEIQSMCWFzQUSgEgpwqRqwFHV1AQA "Jelly – Try It Online")
`oFẸḤƊ$€` is "borrowed" from @Riolku lol [go upvote him](https://codegolf.stackexchange.com/a/200852/68942)
# Explanation
```
n⁶Zṣ1€oFẸḤƊ$€j1€W$Zị“|\ ”  Main Link
n⁶                         vectorized inequality to space; "|" becomes 1, " " becomes 0
  Z                        transpose into a list of columns
   ṣ1€                     split by [1, 1, ..., 1] (length of original; number of rows)
            €              for each block (space between two lines)
      o                    vectorized OR with
       FẸḤ                 (flatten) (any) (double): 0 if there are only spaces; 2 if there are lane dividers
             j             join on
              1€W$         [1, 1, ..., 1] wrapped ([[1, 1, ..., 1]])
                  Z        zip back into original orientation
                   ị“|\ ”  index into "|\ "; 0s are spaces, 1s are lines, and 2s are the replaced spaces which become \
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 25 bytes
```
Zn⁶ṣoFẸḤƊ$€jW}
ç1€ị“|\ ”Z
```
[Try it online!](https://tio.run/##y0rNyan8/z8q71Hjtoc7F@e7Pdy14@GOJce6VB41rckKr@U6vNwQyHq4u/tRw5yaGIVHDXOj/j/cveVwe@T//zUKCgo1YAikuSA8BRQeVjkA "Jelly – Try It Online")
I/O is a list of strings
# Explanation
```
Zn⁶ṣoFẸḤƊ$€jW}   Primary Link (dyad); takes the input on the left and [1, 1, ..., 1] on the right
Z                zip the input into a list of columns
 n⁶              vectorized inequality to space; "|" becomes 1, " " becomes 0
   ṣ             split (on [1, 1, ..., 1])
          €      for each block (between lines)
    o            vectorized or with
     FẸḤ         (flatten) (any) (double): 0 if there are only spaces; 2 if there are lane dividers
           jW}   join on ([1, 1, ..., 1] wrapped) (2,2-chain using })
ç1€ị“|\ ”Z       Main Link
ç                call the primary link with (default left argument),
 1€              [1, 1, ..., 1]
   ị“|\ ”        index into "|\ "
         Z       zip back into original orientation
```
[Answer]
# [Haskell](https://www.haskell.org/), 151 bytes
```
a#b=a!!mod b(length a)
z=zip[0..]
s%_=[[(['\\'|b<'!'&&(s#(x-1)#y>'['||elem '\\'[a#(y-1),a#(y+1)])]++[b])!!0|(y,b)<-z a]|(x,a)<-z s]
g x=foldl(%)x(x!!0)
```
[Try it online!](https://tio.run/##hYoxb8MgGER3fsWHnASQ7SjZTZau7dSRoAhk6qBibBUqYYv/7jqNFCldOpzu9O5dVfg0zi2LKjRXGPdDC5o647t4BcXQzGc7isN@L1HYXrgQVJDzmWTdEEx2OxoKmuojK6YTESRn40wPN0Gogk7rUd26PDLJZFkKLRnGh0ynSrOmnkHJTFOlfneQqIPEPwbXOrpliaZVZUuvrOftgAAsNDU4602AZnOCzsSXwUfjY1jPXo1vFxi/43v8evWwgQ7sAhngEbh3BvSE853/xf/ZPw "Haskell – Try It Online")
## Explanation
This implements the same algorithm as [my python answer](https://codegolf.stackexchange.com/a/200842). It implements a simple automaton. At every step a space is replaced with an `\` iff at least one of the following is true
* There is a `|` or `\` above it (indexing wraps around)
* There is `\` to the left or right of it.
This means that rain starts at the gaps in the lane dividers and spreads until it hits `|`s.
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 79 bytes
```
+m`(?<=(.)+) ((?<=(?(1).)^(?<-1>.)+\S.*¶.+|\\ )|(?=\\|.*¶(?<-1>.)+(?(1)$)\S))
\
```
[Try it online!](https://tio.run/##K0otycxL/P9fOzdBw97GVkNPU1tTQQPMtNcw1NTTjAOydQ3tgOIxwXpah7bpadfExCho1mjY28bE1IBE4ArAOlQ0Y4I1Nbli/v9XqFFQgGEo4gLzFeBiCnAx2qoDAA "Retina 0.8.2 – Try It Online") Same flood fill approach that @WheatWizard uses in his answers but using .NET balancing groups to detect vertical matches. Would save two bytes if the wind was blowing the other direction. Explanation:
```
+m`
```
Repeatedly replace and turn on line detection.
```
(?<=(.)+) 
```
Replace a space but count the number of preceding characters on that line.
```
((?<=...|...)|(?=...|...)))
\
```
Replace with a backslash if one of the four conditions is true.
The four conditions are:
```
(?(1).)^(?<-1>.)+\S.*¶.+
```
This space is below rain or a lane divider. The `(?(1).)` can only succeed if the characters are in the same column.
```
\\ 
```
This space is to the right of existing rain.
```
\\
```
This space is to the left of existing rain.
```
.*¶(?<-1>.)+(?(1)$)\S
```
This space is above rain or a lane divider. The `(?(1)$)` can only succeed if the characters are in the same column.
[Answer]
# [Ruby](https://www.ruby-lang.org/), 144 bytes
```
->s{s.map{|l|((r=s[0]).size.times.map{|i|r[i]!=s[1][i]?[r.rindex(?|,i-1),r.index(?|,i+1)]:p}-[p]).map{|a,b|a.upto(b){|i|l[i]=?\\if l[i]<?!}};l}}
```
[Try it online!](https://tio.run/##xVLLboMwELzzFZv0AipYIe@0TfkQgipoQLJEKAIitY35dmoextgmSqoeigCtZ2dmd63NzsFXFcEeKus1v@To5KcXEhNdz/a5O/MMlOPvEBX4FHY5TDIXexOatT0aOG6GMpwcw0/dISa2bMPMED8/2ob3lJaWm1KrRu@bAfHROS0@9MCo7WLqsncOBxxBHb44k7J8jsuy0oowL95s2purAX2mQOi/@7p3ag5S0KdATv2rytPaUeZ8FAI9kQwNmDXLCrjIZ66LwQV1DXUuvK0ekib5O591sRRnIwMLIs0h5Udzd@pY9ZVcfeRaydid3mSyCmuhgroUBPjFDMHbTFZhI81QaxSRiPyKw@psR7ZwpMN7YGa5E1ZQXqVrZ6a2Z6J8SJViKjmGEdQyHSfpuTAhMhoGjXNooP7I8Qi9@3HcKjhdC5Nj24Le9tGYPQBH5gqyUJClgqwUZK0gGwXZKshOQexZDVU/ "Ruby – Try It Online")
I thought I would try a different approach to the automaton. This finds lane dividers by checking for which indices the first two rows differ. It then goes through each of these indices and finds the previous and next line. It then fills in all space characters with the rain character.
This takes a list of strings for each row of the road.
### Golfy Tricks:
* Using `l[i]<?!` instead of `l[i]==" "`. This checks to see whether the character comes before `!` (which [only space does](http://www.asciitable.com/) of the allowed charactersin this challenge).
* `-[p]` to remove all `nil` elements in an array.
* `map` instead of `each`.
* `size.times` instead of `chars.each_index`
* Using `map` with a condition (where failures result in `nil` and `nil`s are then removed), rather than a `select` followed by a `map`.
### Explanation:
```
->s{s.map{|l|((r=s[0]).size.times.map{|i|r[i]!=s[1][i]?[r.rindex(?|,i-1),r.index(?|,i+1)]:p}-[p]).map{|a,b|a.upto(b){|i|l[i]=?\\if l[i]<?!}};l}}
# Go through each character in the first row (saving the row in a variable for later use)
             ((r=s[0]).size.times.map
# Check if it's a line divider
                                         r[i]!=s[1][i] 
# If it is, save the nearest road lines
                                                       [r.rindex(?|,i-1),r.index(?|,i+1)]
# If it isn't save nil
                                                                                          p 
# Remove all the nils
                                                                                            -[p]
# So we have all the indices of the lanes
             ((r=s[0]).size.times.map{|i|r[i]!=s[1][i]?[r.rindex(?|,i-1),r.index(?|,i+1)]:p}-[p]) 
# For each row in the road
->s{s.map{|l| 
# Go through each index within the lane
                                                                                                 .map{|a,b|a.upto(b) 
# And set any empty charaters to rain
                                                                                                                        l[i]=?\\if l[i]<?! 
# And then return the new rainy row
                                                                                                                                             l
```
[Answer]
# [Bash](https://www.gnu.org/software/bash/) + Core utilities, ~~154~~ ~~152~~ ~~145~~ ~~142~~ ~~136~~ 119 bytes
```
IFS=\
read t
d=`sed s/././g<<<$t`
sed -E ":l;s/([|%]$d|%) /\1%/;tl;s/ ($d[|%]|%)/%\1/;tl;"'y/%@/\\\
/'<<<$t@`tr '
' @`
```
[Try it online!](https://tio.run/##S0oszvj/39Mt2DaGi6soNTFFoYQrxTahODVFoVhfDwjTbWxsVEoSuEAiuq4KSlY51sX6GtE1qrEqKTWqmgr6MYaq@tYlIFEFDZUUkARQWF81xhAsqqReqa/qoB8TE8Olrw42yiGhpEhBnUtdwSHh/3@FGgUFGIYiLjBfAS6mABejrToA "Bash – Try It Online")
Input on stdin, and output on stdout.
(The script has spurious output to stderr in one case, but that's considered acceptable.)
Here are the outputs for the test cases:
```
highway-1-simple
 |\\\|\\\|  |\\|\\|
 |\\\\\\\|  |\\\\\|
 |\\\|\\\|  |\\|\\|
 |\\\\\\\|  |\\\\\|
 |\\\|\\\|  |\\|\\|
 |\\\\\\\|  |\\\\\|
 |\\\|\\\|  |\\|\\|
highway-2-extraline
|\\\\|\\\|\|   |
|\\\\\\\\\\|   |
|\\\\|\\\|\|   |
highway-3-unsyncedlanedividers
   |\\\\|\\\\\\|
   |\\\\\\\\|\\|
   |\\\\|\\\\\\|
   |\\\\\\\\|\\|
   |\\\\|\\\\\\|
highway-4-emptyroad
|   |   |\\\\\\\|\\|
|   |   |\\\|\\\\\\|
|   |   |\\\\\\\|\\|
|   |   |\\\|\\\\\\|
highway-5-falseroads
|   |\|\|   |
|   |\\\|   |
|   |\|\|   |
|   |\\\|   |
highway-6-hardlanedivider
|\\|\\|\\|\\|
|\\\\\|\\\\\|
|\\|\\|\\|\\|
|\\\\\|\\\\\|
highway-7-adjacentlanedividers
|\\\||\\||
|\\\\\|\||
|\\\||\\||
|\\\\\|\||
|\\\||\\||
highway-8-nolanes
|    |     |  |
|    |     |  |
|    |     |  |
highway-9-oneline
       |
       |
       |
highway-A-nolines
```
[Answer]
# [Husk](https://github.com/barbuz/Husk), ~~21~~ ~~20~~ 15 bytes
*-5 bytes thanks to [Zgarb](https://codegolf.stackexchange.com/users/32014)!*
```
Tṁ?mσ' '\IV≠ġ▼T
```
[Try it online!](https://tio.run/##yygtzv5/aNujpsZD2/6HPNzZaJ97vlldQT3GM@xR54IjCx9N2xPy//9/JYUaBQUYhiIuMF8BLqYAF6OtOiUA////Sgo1CgowDEVcYL4CXEwBLkZbdUoA "Husk – Try It Online") Takes input as a list of rows. Works by transposing rows and columns, splitting the columns into groups based on whether they have any spaces, adding rain to the column groups with lane divisions, recombining the column groups, and transposing back.
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 33 bytes
```
ＷＳ⊞υ⪫⪪ι ψＰ⪫υ¶Ｆ⊟υ¿⊖№ＫＤ²↓|ＫＫ«¤\↓¤\↗
```
[Try it online!](https://tio.run/##tY09j8IwDIZn@iusTI5UFkYYrzrpkJAqEFsX1DPUupBEIQEh4LcHt3xMrCfZg18/ftx2m9C6jcn51LEhwB/rU1zFwHaHWkOdDh2mEuaOLa684YhcggKlSzhrPSsWyUT2gkccGGFVY1W/2roAWDuPSUS8BayoDbQnG@kXv1ySk5ror@JAbWRncVLCtHInK251FYW8H8Q9hb2RzIHgUoy@2RhUTaMkGy3ckfBxN/u4Wvsl77oowS1nuAK8@lnFMMM7g3f2z1weH80d "Charcoal – Try It Online") Link is to verbose version of code. Expects rectangular input with newline terminator. Explanation:
```
ＷＳ⊞υ⪫⪪ι ψ
```
Read the input but change spaces into nulls.
```
Ｐ⪫υ¶
```
Copy the input to the output; nulls turn into fillable spaces.
```
Ｆ⊟υ
```
Loop over the width of the input.
```
¿⊖№ＫＤ²↓|
```
Is this a lane divider? It isn't if it doesn't alternate between `|`s and empty cells.
```
ＫＫ
```
If it's not a divider then print the current character thus moving the cursor one step right. Simply moving right doesn't help because this needs to be a two-character Move command to avoid confusion with printing a lambda in a rightwards direction, and negating the condition doesn't help because when there are no lanes then Charcoal prints nulls instead of spaces for some inexplicable reason.
```
«¤\↓¤\↗
```
Fill the area with rain. Both the current cell and the cell below need to be checked as we don't know which one is empty. The cursor is then moved to the right of its original position.
]