Translate English to English

You have been hired by the American embassy in the UK to act as a translator. Being a programmer, you decide to write a program to do a bit of the work for you.

You've found out that often just doing the following things can satisfy Word's spellcheck, which has been set to "English (United States)", somewhat, so you don't have to do as much work later when translating written documents:

• All occurrences of "our" can be replaced with "or", e.g. "favourite" -> "favorite", "our" -> "or".
• All occurrences of "ise" and "yse" can be replaced with "ize" and "yze", respectively.
• All occurrences of "ae" and "oe" can be replaced with "e".
• All occurrences of "ll" that have a vowel before them can be replaced with "l".
• The ending "re" can re replaced with "er", as long as it is not preceded by a vowel, e.g. "ore" will not be replaced, but "centre" becomes "center".
• The ending "xion" can be replaced with "ction", e.g. "connexion" -> "connection" (this is archaic, but whatever).

Write a program or function that takes a string or list of characters as input, performs the replacements mentioned above, and outputs the modified string or list of characters using the standard IO methods.

Rules

• A sequence of alphabetical characters is considered a word ([A-Za-z]). Words may be delimited by spaces, hyphens, commas, periods, or other punctuation characters ([^A-Za-z]).
• A vowel is one of a, e, i, o, or u.
• This is , so shortest code wins.
• Inputs with conflicts are undefined behavior, e.g. if a word ends with "oure", your program can make it "ouer" or "ore".
• Your program need only take one pass over the input - it's fine if you replaced something like "rae" and end up with "re" instead of further turning that into "er".
• Substitutions may be done on uppercase and/or lowercase letters (you can choose). You may also output the letters in any case you want.

Test cases

Note that not all words have been translated correctly, since the rules described above are not always right. Also note that the text here has mixed case to try to look like normal English, but you can use all lowercase for your input and all uppercase for your output or whatever you want.

Substitutions are bolded or italicized if they are side by side.

Input
---
Output
______
We would like you to analyse something our agencies have discovered.
---
We would like you to analyze something or agencies have discovered.
______
There have been reports of American tourists travelling here in knight's armour.
---
There have been reports of American torists traveling here in knight's armor.
______
An aerosol may be the cause of their transfixion. Their oesophagi must be studied.
---
An erosol may be the cause of their transfiction. Their esophagi must be studied.
______
OURoullisaeisere
---
ORouliseizere
______
Pardon me, I just fell on my keyboard while dodging a knight with a metre-long sword.
---
Pardon me, I just fel on my keyboard while dodging a knight with a meter-long sword.
______
My keysere n'twourkingnowneithre r myhands hellllpme
---
My keyzere n'tworkingnowneither r myhands helllpme
______
Haha, I'm just messing with you. No knights here with 3.28-foot-long swords. That's totally ridiculous.
______
Haha, I'm just messing with you. No knights here with 3.28-foot-long swords. That's totaly ridiculous.

• Is the input guaranteed to be printable ASCII, or do we have to support other Unicode characters as well? – Kevin Cruijssen Dec 9 '20 at 9:49
• @KevinCruijssen Sure, if you need to. No need to support Unicode – user Dec 9 '20 at 12:18
• What should be the output for metres? No change? – vrintle Dec 9 '20 at 16:32
• @vrintle Yes, no change. It doesn't end in re. – user Dec 9 '20 at 20:50
• Accoring to your rules, "this is our home" shall be translated into "this is or home", correct? – Daemon Painter Dec 10 '20 at 11:16

-2 thanks to Neil.

our
(i|y)se
ae|oe
([aeiou]l)l
([^aeiou])re\b
xion\b
or
\1ze
e
\1
\1er
ction


Try it online!

The first half of the strings are PCRE patterns while the latter half are their substitutions.

• Why not (i|y)? – Neil Dec 8 '20 at 20:15
• l)l saves another byte. – Neil Dec 8 '20 at 20:18
• @Neil Because I didn't sleep last night. – Adám Dec 8 '20 at 20:20

Perl 5, -p100 94 bytes

Saves 6 bytes since we can require all input to be lowercase, as pointed out by @NahuelFouilleul

s/our/or/g;s/[iy]\Kse/ze/g;s/ae|oe/e/g;s/[aeiou]l\Kl//g;s/[^aeiou]\Kre\b/er/g;s/xion\b/ction/g


Try it online!

• /i modifiers may be removed ; from the question Substitutions may be done on uppercase and/or lowercase letters (you can choose). – Nahuel Fouilleul Dec 8 '20 at 20:38

Charcoal, 130 125 bytes

≔aeiouζ≔⁺ θηＦiy≔⪫⪪θ⁺ιse⁺ιzeθＦ⌕ＡθreＦ¬∨№ζ§ηι№β§η⁺³ι≔⭆Φθ⁻μι⎇⁻μιλerθ⭆θ⎇∨№⁺⊕⌕Ａθour⁺⌕Ａθae⌕Ａθoeκ∧№⌕Ａθllκ№ζ§ηκω⎇∧№⌕Ａθxionκ¬№β§η⁺⁵κctι


Try it online! Link is to verbose version of code. Expects lowercase input. Explanation:

≔aeiouζ


Get the vowels in a variable, as they're long enough for this to save a byte.

≔⁺ θη


Make a copy of the input with a space prepended. This is used for cyclic indexing, plus conveniently offsets the indices by one.

Ｆiy≔⪫⪪θ⁺ιse⁺ιzeθ


Replace ise and yse with ize and yze respectively.

Ｆ⌕Ａθre


Find all occurrences of re...

Ｆ¬∨№ζ§ηι№β§η⁺³ι


... that are at the end of a word and do not follow a vowel...

≔⭆Φθ⁻μι⎇⁻μιλerθ


... and replace them with er.

⭆θ⎇∨№⁺⊕⌕Ａθour⁺⌕Ａθae⌕Ａθoeκ∧№⌕Ａθllκ№ζ§ηκω⎇∧№⌕Ａθxionκ¬№β§η⁺⁵κctι


If the current character is:

• the u of our
• the a of ae
• the o of oe
• or the first l of ll and it follows a vowel

... then delete it, otherwise if it is the x that begins xion at the end of a word then replace it with ct, and output the final result.

JavaScript (ES9), 126 bytes

Operates on lowercase patterns.

s=>s.replace(/(?<=o)u(?=r)|(a|o|(?<=i|y)s)(?=e)|(?<=[aeiou])l(?=l)|(?<![aeiou])re\b|x(?=ion)/g,s=>[{x:'ct',re:'er',s:'z'}[s]])


Try it online!

How?

All operations are processed within a single replace() with a callback function.

We use lookbehind and lookahead assertions so that the sub-strings that actually need to be modified are as small as possible and the replacement is just an implicit empty string whenever possible.

The non-empty replacement strings are stored in an object.

 pattern              | replacement
----------------------+------------------------------
(?<=o)u(?=r)         | "u" -> ""
(a|o|(?<=i|y)s)(?=e) | "a" or "o" -> "", "s" -> "z"
(?<=[aeiou])l(?=l)   | "l" -> ""
(?<![aeiou])re\b     | "re" -> "er"
x(?=ion)             | "x" -> "ct"

Ruby-p, 110101 100 bytes

A port of Arnauld's answer in Ruby.
Saved a whooping 9+1 bytes using \K, thanks to Dingus!!

gsub /o\Ku(?=r)|(a|o|[iy]\Ks)(?=e)|[aeiou]\Kl(?=l)|[^aeiou]\Kre\b|x(?=ion)/,?s=>?z,'re'=>:er,?x=>:ct


Try it online!

• that moment when ruby is shorter than charcoal.. – Razetime Dec 9 '20 at 9:01
• @Razetime It was hard enough getting Charcoal shorter than JS (regexp helping JS a lot here). – Neil Dec 9 '20 at 10:55
• @Neil I know the feeling (just posted my 05AB1E answer). Lack of regex is annoying for this challenge.. :/ – Kevin Cruijssen Dec 9 '20 at 11:16
• @KevinCruijssen At least you have a vowels builtin... – Neil Dec 9 '20 at 12:14
• You can shorten this a bit using \K: Try it online!. (Removed test cases only because the link was too long for a comment.) – Dingus Dec 10 '20 at 5:30

05AB1E, 94 bytes

.•´iÈQ<¾Ÿ7ø₂2>“UcтλHZ•#2ä.:žMS„ll«D€¨.:DžQAKS¡DεD"xion"Å¿i¨¨¨¨.•U®$•«}žNvDy„re«Å¿i¨¨¨y„erJ].;  Input in lowercase. Assumes the input will only contains printable ASCII characters. Explanation: .•´iÈQ<¾Ÿ7ø₂2>“UcтλHZ• # Push compressed string "our ise yse ae oe or ize yze e e" # # Split it on spaces: ["our","ise","yse","ae","oe","or","ize","yze","e","e"] 2ä # Split into 2 equal-sized blocks: [["our","ise","yse","ae","oe"],["or","ize","yze","e","e"]]  # Pop and push both lists separated to the stack .: # Replace all žM # Push builtin "aeiou" S # Convert it to a list of characters: ["a","e","i","o","u"] „ll« # Append "ll" to each: ["all","ell","ill","oll","ull"] D€¨ # Duplicate it, and remove the last character of each: ["al","el","il","ol","ul"] .: # Replace all D # Duplicate the current string žQ # Push a builtin with all printable ASCII characters AK # Remove the lowercase alphabet from it S # Split it to a list of characters ¡ # And split the duplicated string on these non-letter characters D # Duplicate the list of words ε # Map over each word: D # Duplicate the current word "xion"Å¿i } # Pop, and if it ends with "xion": ¨¨¨¨ # Remove the final four characters from the word .•U®$•«    #   And append (compressed) "ction"
žN                   #  Push buitin "bcdfghjklmnpqrstvwxyz"
v                  #  Loop y over each of its characters:
D                 #   Duplicate the current word
y„re«            #   Push the current consonant, and append "re"
Å¿i         #   If it ends with "Cre" (where C is the consonant)
¨¨¨      #    Remove the final three characters from the word
y„erJ    #    Push the consonant and "er" and join all three together
]                      # Close the open if-statement, loop, and map
.:                    # And replace all
# (after which the result is output implicitly)


See this 05AB1E tip of mine (section How to compress strings not part of the dictionary?) to understand why .•´iÈQ<¾Ÿ7ø₂2>“UcтλHZ• is "our ise yse ae oe or ize yze e e" and .•U®\$• is "ction".

Python 3.8, 158 154 bytes

Saved 4 bytes thanks to user!!!

lambda s:[(s:=re.sub(*x.split(),s))for x in r'our or|ise ize|yse yze|[ao]e e|(?<=[aeiou])ll l|(?<=[^aeiou])re\b er|xion\b ction'.split('|')][-1]
import re


Try it online!

Inputs a string in lower-case and returns its translation in lower-case.

• Instead of a newline + indent for return, you can just use ;, making it x.split(),s);return s on line 3, saving 1 byte. – John Zhau Dec 10 '20 at 2:51
• @JohnZhau Not on the same line as a for loop, that'll make it return at the end of the first loop. – Noodle9 Dec 10 '20 at 8:23
• You can get 154/156 bytes with import re f=lambda s:[(s:=re.sub(*x.split(),s))for x in r'our or|ise ize|yse yze|[ao]e e|(?<=[aeiou])ll l|(?<=[^aeiou])re\b er|xion\b ction'.split('|')][-1] (sorry, TIO link was too big). reduce may have been even shorter, although the import is rather long – user Dec 10 '20 at 16:10
• @user Sweet - thanks! :D – Noodle9 Dec 10 '20 at 22:00