g | x | w | all
Bytes Lang Time Link
125AWK250916T143501Zxrs
nanWolfram Language Mathematica230408T132742Z138 Aspe
106Lexurgy220121T005519Zbigyihsu
100Ruby p201209T033547Zvrintle
154Python 3.8201209T144925ZNoodle9
126JavaScript ES9201208T214512ZArnauld
09405AB1E201209T111514ZKevin Cr
125Charcoal201208T222854ZNeil
094Perl 5201208T202821ZXcali
075QuadR201208T201053ZAdá

AWK, 125 bytes

{split("our ise yse ae|oe ([aeiou])ll [^aeiou]re xion or ize yze e \\1l er ction",a)
for(;i++<7;)$0=gensub(a[i],a[i+7],"g")}1

Attempt This Online!

Works on lower case. If we add BEGIN{IGNORECASE=1} to the beginning it'll match uppercase as well, but print lowercase.

If we work a little harder we can do some uppercase matching and printing, too (175 bytes):

{split("our ise yse ae|oe ([aeiou])ll [^aeiou]re xion",a)
split("or ize yze e \\1l er ction",b)
for(;i++<12;)$0=gensub(i<7?a[i]:toupper(a[i-6]),i<7?b[i]:toupper(b[i-6]),"g")}1

Wolfram Language (Mathematica), 227 181 bytes

saved 46 bytes thanks to comment.

Try it online!

R:=RegularExpression
f[s_]:=StringReplace[s,{"our"->"or","ise"->"ize","yse"->"yze","ae"->"e","oe"->"e",R["(?<=[aeiou])ll"]->"l",R["(?<=[^aeiou])re\\b"]->"er",R["xion\\b"]->"ction"}]

Ungolfed version:

f[s_String] := Module[
  {replacements, result},
  replacements = {
    "our" -> "or",
    "ise" -> "ize",
    "yse" -> "yze",
    "ae" -> "e",
    "oe" -> "e",
    RegularExpression["(?<=[aeiou])ll"] -> "l",
    RegularExpression["(?<=[^aeiou])re\\b"] -> "er",
    RegularExpression["xion\\b"] -> "ction"
  };
  result = StringReplace[s, replacements];
  result
]

Lexurgy, 106 bytes

Sound changes are what Lexurgy is made for!

Works in all lowercase only.

Class v {a,e,i,o,u}
o:
our=>or
{i,y} se=>{i,y} ze
{a,o}=>*/_ e
l=>*/@v _ l
re=>er/!@v _
x=>ct/_ ion

Ungolfed explanation:

# define vowels
Class vowel {a,e,i,o,u}

or:
our=>or

ize:
{i,y} se=>{i,y} ze

e:
{a,o}=>*/_ e

l:
l=>*/@vowel _ l

er:
re=>er/!@vowel _

ction:
x=>ct/_ ion

Ruby -p, 110 101 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!

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.

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"

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.

Try it online or verify all test cases.

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".

Charcoal, 130 125 bytes

≔aeiouζ≔⁺ θηFiy≔⪫⪪θ⁺ιse⁺ιzeθF⌕AθreF¬∨№ζ§ηι№β§η⁺³ι≔⭆Φθ⁻μι⎇⁻μιλerθ⭆θ⎇∨№⁺⊕⌕Aθour⁺⌕Aθae⌕Aθoeκ∧№⌕Aθllκ№ζ§ηκω⎇∧№⌕Aθ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.

Fiy≔⪫⪪θ⁺ιse⁺ιzeθ

Replace ise and yse with ize and yze respectively.

F⌕Aθre

Find all occurrences of re...

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

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

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

... and replace them with er.

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

If the current character is:

... 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.

Perl 5, -p 100 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!

QuadR, 77 75 bytes

-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.