# Replace backslash escape only in old posts after import

**URL:** https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891
**Category:** Support
**Created:** [February 18, 2018, 5:20pm UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891 "2018-02-18T17:20:08Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![fhe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fhe/32/113345_2.png) [@fhe](https://meta.discourse.org/u/fhe)
#### Post date: [February 18, 2018, 5:20pm UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/1 "2018-02-18T17:20:08Z")

</div>

I’ve imported a forum where we made heavy use of this combination of characters  
`\%`  
which is now reduced to the percent sign due to markdown (?) processing  
% (I’ve also used the backslash here, but omitted the code ticks)

Is there a way to

1. exclude the `\%` combination from being processed in a special way, or
2. to replace the `\%` combination to `\\%` but only for post-import posts?

Thanks for any pointers.

---

<div class="post-metadata">

### Author: ![schungx](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/schungx/32/70989_2.png) [@schungx](https://meta.discourse.org/u/schungx)
#### Post date: [February 18, 2018, 9:57pm UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/2 "2018-02-18T21:57:48Z")

</div>

There are ways to globally replace a text string in all posts and then recook all the posts.

---

<div class="post-metadata">

### Author: ![fhe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fhe/32/113345_2.png) [@fhe](https://meta.discourse.org/u/fhe)
#### Post date: [February 19, 2018, 8:23am UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/3 "2018-02-19T08:23:11Z")

</div>

I’m aware of `rake posts:remap["find","replace"]`.

In this specific case I guess it would be

`rake posts:remap["\\%","\\\\%"]`

However, when looking [at the code](https://github.com/discourse/discourse/blob/master/lib/tasks/posts.rake#L130-L152), it seems like regexp is also supported.

So something like

`rake posts:remap["(?<=[^\\])\\%","\\\\%","regex"]`

should replace all occurrences of `\%` which are not preceded by another `\`. But it seems this regexp is then passed along to the database layer which doesn’t support lookbehinds.

It’s tricky. Thanks for any further ideas.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [February 19, 2018, 12:38pm UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/4 "2018-02-19T12:38:12Z")

</div>

To fix those just before the forum went live you could do it from the rails console and each /search by date.

---

<div class="post-metadata">

### Author: ![fhe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fhe/32/113345_2.png) [@fhe](https://meta.discourse.org/u/fhe)
#### Post date: [February 19, 2018, 12:43pm UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/5 "2018-02-19T12:43:06Z")

</div>

> [@pfaffman](#):
>
> To fix those just before the forum went live you could do it from the rails console and each /search by date.

Can you give an example?

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [February 19, 2018, 12:49pm UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/6 "2018-02-19T12:49:18Z")

</div>

I’ve posted a few examples that I can’t find from my phone. I think I posted code about deactivating all users that could be an example.

---

<div class="post-metadata">

### Author: ![fhe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fhe/32/113345_2.png) [@fhe](https://meta.discourse.org/u/fhe)
#### Post date: [February 19, 2018, 4:13pm UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/7 "2018-02-19T16:13:10Z")

</div>

This is powerful stuff 🤓 Seems like I’m slowly learning Ruby here.

I’ve thought of something like

```ruby
imported_posts = Post.where("id < 117108")
imported_posts.find_each do |post|
  raw = post.raw.gsub(/(?<=[^\\])\\%/, "\\\\%")
  post.update_column(:raw, raw)
end

```

but unfortunately, it doesn’t replace anything in `Post.raw`. Anything obvious I’m missing?

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [February 19, 2018, 4:41pm UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/8 "2018-02-19T16:41:34Z")

</div>

Try adding

```
   post.save

```

At the end of the loop

---

<div class="post-metadata">

### Author: ![fhe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fhe/32/113345_2.png) [@fhe](https://meta.discourse.org/u/fhe)
#### Post date: [February 19, 2018, 4:59pm UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/9 "2018-02-19T16:59:44Z")

</div>

No, but apparently I was missing some additional escapes. This is what works now:

```plaintext
raw = post.raw.gsub(/(?<=[^\\])\\\%/, '\\\\\%')

```

Using `'\\\\\%'`over `"\\\\\%"`also makes a difference.

Thanks for initially pointing me to the Rails console, @pfaffman!

---

<div class="post-metadata">

### Author: ![Mittineague](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mittineague/32/114259_2.png) [@Mittineague](https://meta.discourse.org/u/Mittineague)
#### Post date: [February 19, 2018, 8:28pm UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/10 "2018-02-19T20:28:22Z")

</div>

> [@fhe](#):
>
> makes a difference.

Yes, escapes in strings inside single quote marks are literal strings, all escapes intact. Escapes inside double quote marks get escaped before going to the next piece of code. i.e.  
‘\\\\’ goes as ‘\\\\’ while “\\\\” goes as ‘\\’  
Similar with ‘&amp;’ → ‘&amp;’ vs “&amp;” → ‘&’

Can be a gremlin that’s not so easy to pin down.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [February 19, 2018, 8:54pm UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/11 "2018-02-19T20:54:29Z")

</div>

> [@fhe](#):
>
> Thanks for initially pointing me to the Rails console, @pfaffman!

Glad the push was all you needed!

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [June 3, 2020, 10:16am UTC](https://meta.discourse.org/t/replace-backslash-escape-only-in-old-posts-after-import/80891/12 "2020-06-03T10:16:42Z")

</div>


