[Question]
  [
# Guidelines
## Scenario
John has an important number, and he doesn't want others to see it.
He decided to encrypt the number, using the following steps:
His number is always a non-decreasing sequence (ie. `"1123"`)
He converted each digit into English words. (ie. `"123" -> "ONETWOTHREE"`)
And then, rearrange the letters randomly. (ie. `"ONETWOTHREE" -> "ENOWTOHEETR"`)
John felt that his number were safe in doing so. In fact, such encryption can be easily decrypted :(
---
## Task
Given the encrypted string s, your task is to decrypt it and return the original number.
---
## Rules
* This is code golf, so the shortest answer in bytes wins
* You can assume that the input string is always valid
* The input string only contains uppercase letters
* The original numbers are always arranged in ascending order
* You may return the number in string or integer format
* The letters will only be shuffled between one word, not between the whole string.
* The numbers will only be from 1 to 9 inclusive (`ONE` to `NINE`)
---
## Possible Unscrambled String
Here is a list of the strings just after they have been converted to strings from the numbers:
```
 1 -> ONE 
 2 -> TWO
 3 -> THREE
 4 -> FOUR
 5 -> FIVE
 6 -> SIX
 7 -> SEVEN
 8 -> EIGHT
 9 -> NINE
```
---
## Examples
`"NEO" -> 1`
`"ENOWOT" -> 12`
`"EONOTWHTERE" -> 123`
`"SNVEEGHEITNEIN" -> 789`
`"ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN" -> 123456789`
`"NOEWOTTOWHEERT" -> 1223`
  
[Answer]
# Python 2, ~~121~~ ~~117~~ 115 bytes
```
def g(s,a=0,f=''):
 for c in s:
    a+=34**ord(c)%43;r='P!\x83u\x8eI\x92|Z'.find(chr(a))+1
    if r:f,a=f+`r`,0
 return f
```
-4 bytes: After all that golfing I forgot to inline a single-use variable. Brain fart.  
-2 bytes: Double-spaced indent → single tab indent (thanks to Coty Johnathan Saxman); note that this does not display correctly in the answer.
## Ungolfed (compatible with python 3):
```
nums = [80, 33, 131, 117, 142, 73, 146, 124, 90]
def decode(str):
    acc = 0
    final = ''
    for c in str:
        acc += (34**ord(c))%43
        if acc in nums:
            final += str(1+nums.index(acc))
            acc=0
    return final
```
## Magic number finder:
```
#!/usr/bin/env python3
from itertools import count, permutations
def cumul(x):
    s = 0
    for v in x:
        s += v
        yield s
all_words = 'ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split()
for modulo in range(1, 1000):
    for power in range(1, 300):
        combinations = []
        for word in all_words:
            my_combination = []
            for perm in permutations(word):
                my_combination += cumul(power**(ord(x)) % modulo for x in perm)
            combinations.append(my_combination)
        past_combinations = set(())
        past_intermediates = set(())
        collision = False
        for combination in combinations:
            final = combination[-1]
            if final in past_intermediates or any(intermediate in past_combinations for intermediate in combination):
                collision = True
                break
            past_combinations.add(final)
            past_intermediates.update(combination)
        if not collision:
            print("Good params:", power, modulo)
            print("Results:", ", ".join(str(x[-1]) for x in combinations))
```
## Explanation:
I had a feeling that I could smash the ASCII bits together and sum them up somehow to determine when I had a full word. Originally I tried messing with `3**ord(letter)` and comparing to expected results, but it resulted in some very large numbers. I though it would be appropriate to brute-force some parameters a little, namely modulus (to ensure the numbers are small) and a multiplier to disperse the numbers differently around the range of the modulus.
I ended up changing the multiplier variable into a variable affecting the power itself because (from trial and error) that somehow managed to give me a slightly shorter golfed answer.
And above you see the results of that brute-forcing and a little manual golfing.
The reason for choosing `3**x` originally is because I knew you could represent every number there. The most repeated digits any number had is two (thrEE, sEvEn, NiNe, etc), so I decided to think of every input as a base-3 number. That way I could (mentally) represent them as something like `10100000000010020000` (three; a 1 in the `t` slot, a 1 in the `r` slot, a 1 in the `h` slot, and a 2 in the `e` slot). Each number this way gets a unique representation which can be easily pieced together by iterating the string and summing some numbers, and it ends up independent of the actual order of the letters. Of course, this didn't turn out to be the ideal solution, but the current solution is still written with this idea in mind.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~38~~ 37 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
ḟ“RGS”O“OX‘,“¢©“¢¢¤‘yF×4/%74ị⁽G×œ?9¤Ḍ
```
A monadic link taking a list of characters (the string) and returning an integer.
**[Try it online!](https://tio.run/##y0rNyan8///hjvmPGuYEuQc/apjrD2T5RzxqmKEDZBxadGglhFp0aAlQrNLt8HQTfVVzk4e7ux817nU/PP3oZHvLQ0se7uj5//@/q5@/f3iIq2uQR0hQqL@ba5inW4RnsJ9rmGtwiIe7p6urn6cfAA "Jelly – Try It Online")**
Uses a **very different** method to [Pietu1998's Jelly answer](https://codegolf.stackexchange.com/a/131858/53748), ~~yet has the same byte count~~ (~~I really thought it might~~ *it did* end up as less)!
Does not rely on the monotonicity of the original number (so an input of `HTREEWTONOE` would work for example).
### How?
First note that the words themselves (and therefore any anagrams thereof) can all be changed to ones of length 4 by removing any Rs, Gs and Ss and replacing any Os with two characters (say "12") and any Xs with three characters (say "345").
```
letters  -> -RGS  -> O:12, X:345
ONE         ONE      12NE
TWO         TWO      TW12
THREE       THEE     THEE
FOUR        FOU      F12U
FIVE        FIVE     FIVE
SIX         IX       I345
SEVEN       EVEN     EVEN
EIGHT       EIHT     EIHT
NINE        NINE     NINE
```
We may then map the product of the ordinals of those characters to the numbers 1 to 9 using modulo arithmetic, depending upon our choice (the "12345"), then look these up in a reordered list of the digits. The code actually casts to characters first and then replaces the ordinals, but it is also possible in 37 bytes with characters, e.g. "DIAAE" ([try it](https://tio.run/##y0rNyan8///hjvmPGuYEuQc/apgLZPhHAGkdIMPFE0g4OroCuZVu/oenm@irmps83N39qHGv@@HpRyfbWx5a8nBHz////139/P3DQ1xdgzxCgkL93VzDPN0iPIP9XMNcg0M83D1dXf08/QA)).
```
ḟ“RGS”O“OX‘,“¢©“¢¢¤‘yF×4/%74ị⁽G×œ?9¤Ḍ - link: list of characters
 “RGS”                                - literal ['R','G','S']
ḟ                                     - filter discard
      O                               - convert to ordinals
       “OX‘                           - code-page indices list = [79,88]
            “¢©“¢¢¤‘                  - code-page indices lists = [[1,6],[1,1,3]]
           ,                          - pair -> [[79,88],[[1,6],[1,1,3]]]
                    y                 - translate (replace 79s (Os) with [1,6]
                                                       and 88s (Xs) with [1,1,3])
                     F                - flatten into a single list
                       4/             - 4-wise reduce by:
                      ×               -   multiplication (product of each window of four)
                         %74          - modulo 74
                                   ¤  - nilad followed by link(s) as a nilad:
                             ⁽G×      -   base 250 literal = 18768
                                œ?9   -   permutation of [1,2,3,4,5,6,7,8,9] at that
                                      -   index in a lexicographically sorted list of
                                      -   all such permutations -> [1,5,8,2,4,9,7,6,3]
                            ị         - index into
                                    Ḍ - convert from decimal digits to an integer
```
---
### Another 37
```
42BĖZ“Øȧɲ“Pt’żḥ€⁸*/)⁸xO×⁵/%⁽R1%⁽©v%⁵Ḍ
```
[Try it online!](https://tio.run/##y0rNyan8/9/EyOnItKhHDXMOzzix/OQmICOg5FHDzKN7Hu5Y@qhpzaPGHVr6mkCywv/w9EeNW/VVHzXuDTIEkYdWlgGprQ939Pz//9/Vz98/PMTVNcgjJCjU3801zNMtwjPYzzXMNTjEw93T1dXP0w8A "Jelly – Try It Online")
This one repeats characters such that any\* shuffled number name becomes length ten:
| characters | repeat |
| --- | --- |
| G R S T U V | 1 |
| H N | 2 |
| E F I | 3 |
| W | 4 |
| O | 5 |
| X | 6 |
e.g:
```
ONE    => OOOOONNEEE
TWO    => TWWWWOOOOO
THREE  => THHREEEEEE
OURF   => OOOOOURFFF
EVIF   => EEEVIIIFFF
IXS    => IIIXXXXXXS
VENES  => VEEENNEEES
GHIET  => GHHIIIEEET
NINE   => NNIIINNEEE
WOTISX => WWWWOOOOOTIIISXXXXXX
```
Then takes the products of the ordinals of length ten slices and performs a modulo chain to map these to \$[1,9]\$ appropriately.
\* The repetition part works for "ZERO" too -> "ZEEEROOOOO" as 'Z' will also repeat once.
[Answer]
# [Python 2](https://docs.python.org/2/),~~131~~ 127 bytes
```
s=input()
for y in'WXGURFSOIZ':vars()[y]=s.count(y)
while Z<9:s+=[O-U-W,W,R-U,U,F-U,X,S-X,G,I-X-G-F+U][Z]*str(Z+1);Z+=1
print s
```
[Try it online!](https://tio.run/##DcTNCoMgAADge0/hTZ06aLf9eKzWZUIlitFhjI2EYaG24dO7fYdvTXFe3CHnwK1bt4hw8Vo8SMA6qHQju7oXrYGnz90HhMc08bB/LJuLKOHiO9v3E5jL8RQIHwWTTFFFOyappPV/TXumaUNbplnDaiKn0Uy7ED0ypMRnQ3hZrN66CELO8CYqJYZBqGtVdQP8AQ "Python 2 – Try It Online")
Based on a corrected version of the JavaScript [Draco18s](https://codegolf.stackexchange.com/users/47990/draco18s) solution.
[Answer]
# [PHP](https://php.net/), 164 bytes
```
for($c=count_chars($argn);$i<9;)echo str_pad("",[$c[79]-$c[87]-$u=$c[85],$c[87],$c[72]-$g=$c[71],$u,$f=$c[70]-$u,$x=$c[88],$c[86]-$f,$g,$c[73]-$x-$f-$g][+$i],++$i);
```
[Try it online!](https://tio.run/##JVBNa@NADL33V5TgQ0JdaHfZTYsb9rBIHl0kkDVjQwghuPm6xMZNoKf@9VROL6PRG72n96Y/9Ne3f/2hv9sOQzesh23fDefjaT/9gjWL0X@YFXfZZtifFhOsgRDQag1JIIkIo1ICCIRUJX@KUSqIhokbkURMBMGEpQYBMFRjwlihQ7FiTQoWSKEJahYMGQBirGsB1sglSkBgFgUiDWQIRq4FJmFcI4GjamJpQrTEoIAQWQ1GZyCV2yTXK8UhCsDoBh1gISmBylgzKbmPGtBlEX1tBWyiWrtY2QSfbpDMlcTjCrthC@Bb0OfGRJXnaqqQlFUslEwM0TP7SzBzDxBiBZPiuuuGadYu2u5yOq/bw2b4mN5@dFZkx7fXYrZtD939x3lY95v36WSSL7N2OX9dPXp5mXu5LMbbn1X@A4xl/svx/YjPnx245Nnu1jyN43n2eWO8/DD@OrbLs/2N99ubT@@dvVo@ZMdV/uDnrLhevwE "PHP – Try It Online")
# [PHP](https://php.net/), 179 bytes
based on the previous approach check first the even numbers and then the odd numbers in increasing order
```
for($z=[$o=($c=count_chars($argn))[87],$f=$c[85],$x=$c[88],$g=$c[71],$c[79]-$o-$f,$c[72]-$g,$v=$c[70]-$f,$c[86]-$v,$c[73]-$x-$v-$g];$i<9;)echo str_repeat(++$i,$z[_405162738[$i]]);
```
[Try it online!](https://tio.run/##LY9LC8IwEITv/gqRPSRYQeujkRg8SAUvFkTxEEIooa9LE2It4sG/XtcgzLLfLDOHdbUbdntXu1HhvfXaF876rmkr8kn1ObueDinlI8h91YpJdk5R13uGOma3y28mfCitJ/AWEqwgYISxz7bTps79g4QipZIlKoJSgJFsjfQKxJCqHyULJFxbNQM7gzKYGE0VQR8Cc/U/sw1SHwJLpBcajCkOzW7LaWFqO3504Y0i78h0Ck0Eb6lX8/ViEydLJqFRivJh@AI "PHP – Try It Online")
# [PHP](https://php.net/), 201 bytes
```
for(;$o=ord(WUXGOHFVN[$i]);$i++)for(;$r[$o]<count_chars($argn)[$o];$t[]=$i>3?2*$i-7:2+2*$i,sort($t))for(++$r[$o],$n=0;$q=ord(([TO,ORF,IS,HEIT,EN,TREE,IVE,SEEN,NIE][+$i])[$n++]);)$r[$q]++;echo join($t);
```
[Try it online!](https://tio.run/##JY4xa8MwEIX3/IoSbpAqFUo6FKq4Gcol0SJD7LoFIUxwnFgdJOfirv3rruVs797B976@68f1pu/6RUsUqaa2jzT4cGF/WJu81B/I1QKOdAnZsjAV4m6PujSozVKN50hMQcwindjX5/cu328rY8E7rsALwe9/shDduom/Yaib7kg3NvN4qhUM1mXg3182q0fwT69vK5GCvE0aDAY@M4S4QySE7FnBdR5ktsxlfthKXcjkJNHI8oAodYWywOkyGp0VScdCEGKy4olzdUKotuniw0/0IY2ocfwH "PHP – Try It Online")
[Answer]
# Javascript (ES6), ~~288~~ ~~150~~ 144 bytes
```
q=s=>[u=(l=t=>s.split(t).length-1)`U`,l`O`-l`W`-u,l`W`,l`R`-w,u,f=l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g-f].map((n,i)=>`${i}`.repeat(i&&n)).join``
const testCases = ['NEO', 'ENOWOT', 'EONOTWHTERE', 'SNVEEGHEITNEIN', 'ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN']
testCases.forEach(testCase => console.log(testCase, q(testCase)))
```
Longer than ~~the other two~~ one of the other JS entries, but I thought I'd drop an interesting approach that might work for someone in another language.
Essentially we can determine the following:
```
W -> 2
X -> 6
G -> 8
U -> 4
```
Any occurrence of these letters implies that that digit exists in the original number. From here we can deduce the rest of the digits:
```
R-U -> 3
F-U -> 5
S-X -> 7
```
Including the two complicated cases:
```
O-(U+W) -> 1
I-(X+G+(F-U)) -> 9
```
Both `1` and `9` area Hard comparatively. For ONE, `E` shows up more than once in some words (`SEVEN` has two) as does `N` (`NINE`), so we're stuck with checking for `O` which occurs in two other places, fortunately both are simple.
For NINE, nine is hard no matter how you slice it.
Thus we end up with this map:
```
[u=(l=t=>s.split(t).length-1)`U`,  //unused 0; precompute 'U's
 l`O`-l`W`-u,    //1
 l`W`,           //2
 l`R`-w,         //3
 u,              //4
 f=l`F`-u,       //5
 x=l`X`,         //6
 l`S`-x,         //7
 g=l`G`,         //8
 l`I`-x-g-f]     //9
```
9 is able to back-reference siX, eiGht, and Five (with 5 back-referencing foUr) with the variable assignments, saving bytes. Thanks to Neil for this, it uses several features of JS I am very unfamiliar with (the back-ticks for stripping `('` in half, for instance) and actually comes much closer to the idea I'd doodled out on paper before attempting to code it (I'd left 9 as "what's left over", thinking about it as "if I see an `X` I can remove it and an `S` and `I` from the string, then..." so that after the four simple cases the next 3 would *become* simple).
The reason this entry is *interesting* is because it can handle *any shuffled string* as input. i.e. rather than the individual words being shuffled, we can shuffle the whole string, which is what I thought John was doing originally:
```
q=s=>[u=(l=t=>s.split(t).length-1)`U`,l`O`-l`W`-u,l`W`,l`R`-w,u,f=l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g-f].map((n,i)=>`${i}`.repeat(i&&n)).join``
const testCases = ['XENSENINEVSI']
testCases.forEach(testCase => console.log(testCase, q(testCase)))
```
[Answer]
# [C# (.NET Core)](https://www.microsoft.com/net/core/platform), 234 bytes
```
string q(string s){string[]n="ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".Split(',');var r="";int x=0,i=0,j;try{for(;;)for (j=x;;)if(n[i].IndexOf(s[j])>=0){if(++j==n[i].Length+x){r+=i+1;x=j;break;}}else{i++;break;}}catch{}return r;}
```
[Try it online!](https://tio.run/##hVGxTsMwFNz5CisLtmIqmC2zoNfGEthSYppKVYeQuuAQHLBdFBTl20uAio0yPL3T3b0b7tXhou68OeyDdY@o@AjRvLCzEKtoa1S3VQjoptuaRdfuzoYjfwjRf7nf8BEEMvyg9cbxREmgulRUZzkAnav7nM7FEmghVrSAJUgKYpFpKoWEZFa8tjbic3pO2HvlkedJwqyLqOeX1E7TsOg/hl3nMWNkWgg3vJ@g3WG3tpuZcFvTqx0O62ZDrvklGSYlTRvOv@Vb4x7jU9qTwafcples5w178KZ6ZuNo2mAGm6a/RF3F@mkYvYl775Bn4@F1/9BOTRwLee/sFt1V1mEytYGmalzoWjMrvY3m1jqD33AiQSWEsL9kkKpU@pRDKpAg5MkQJZUuMw05nLIVcgmwyEDofwOlUqUGyDOd36s5LMV8JQo5vavQ2UIAyOP9OB4@AQ "C# (.NET Core) – Try It Online")
Expanded version:
```
static string q(string s)
{
    string[] n = "ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".Split(',');
    var r = "";
    int x = 0, i = 0, j = 0;
    try
    {
        for(;;)
            for (j = x; ;)
                if (n[i].IndexOf(s[j]) >= 0)
                {
                    if (++j == n[i].Length + x)
                    {
                        r += i + 1; x = j;
                        break;
                    }
                }
                else
                {
                    i++;
                    break;
                }
    }
    catch { }
    return r;
}
```
Being my first entry, I'm uncertain about the rules... I'm only counting the size of the class used to de-crypt, not the code that tests it, right?
**Edit**
And for the fun of it - here's what I started doing, not reading the complete rules :S - [See it at IdeOne](http://ideone.com/upgxwt). It de-crypts even when characters from one digit can be scrambled to any place in the string.
**Edit 2**
Shortened according to tips by TheLethalCoder. Thanks!
**Edit 3**
And now Titus shaved of a few more bytes. Thanks!
**Edit 4** Six years later :D
As [Magic Octopus Urn](https://codegolf.stackexchange.com/users/59376/magic-octopus-urn) commented, this wasn't working in all cases. Had to add a few bytes to make it work :(
Using try/catch I can ignore boundary checks and save a few bytes :P
[Answer]
# Mathematica, 133 bytes
```
(s={};c=Characters;j=c@#;Table[If[FreeQ[j~Count~#&/@c[#[[i]]]&@ToUpperCase@IntegerName@Range@9,0],s~AppendTo~i],{i,9}];FromDigits@s)&
```
  
**input**
> 
> "VENESGTHIEENNI"
> 
> 
> 
**output**
> 
> 789
> 
> 
> 
[Answer]
# [Retina](https://github.com/m-ender/retina), 88 bytes
```
[EFIST]
^(ON|NO)*
$#1$*1
O
W
2
HR|RH
3
UR|RU
4
X
6
GH|HG
8
(NN)*$
$#1$*9
r`NV|VN
7
V
5
```
[Try it online!](https://tio.run/##JYy9bsJAEIT7eY04knEHJPw8wPj2ml3pbn1GQiBTpEhDgVL63c1Bmhlpvpl5/Pz93m/LZxum5cw@Zr8A19Z0Vlt1aD7WTbeGASM2kDQnwRZD9QFfOGGHILMEHNCqrrrmf3DEY9IyF8UeBd/LojRQbTQHTc1HcSYiayGDMLoy6qtho5NJPA3Ws8T@FLOyMLuESGotuSQy10zx1jdGJXx9aKx5b0NiDOJP "Retina – Try It Online")
**Explanation**
* First, drop a bunch of unnecessary characters not needed for distinctness
* Pick the 1s off the front (this lets us drop the rest of the Os immediately after and clears up some Ns before we get to the 5, 7, 9 mess)
* 2, 3, 4, 6, and 8 are now trivial
* 9s are a double NN, so grab those off the end before we deal with 5 and 7
* Replace 7s from the right (so we don't reduce VNV to 75 instead of 57)
* 5s are the remaining Vs
[Answer]
# JavaScript (ES6), ~~142~~ 139 Bytes
Saved 3 Bytes thanks to [Neil](https://codegolf.stackexchange.com/users/17602/neil).
Doesn't currently take advantage of numbers are always arranged in ascending order
```
f=s=>s?'ENO|OTW|EEHRT|FORU|EFIV|ISX|EENSV|EGHIT|EINN'.split`|`.findIndex(w=>[...s.slice(0,y=w.length)].sort().join``==w)+1+f(s.slice(y)):''
```
```
f=s=>s?'ENO|OTW|EEHRT|FORU|EFIV|ISX|EENSV|EGHIT|EINN'.split`|`.findIndex(w=>[...s.slice(0,y=w.length)].sort().join``==w)+1+f(s.slice(y)):''
const testCases = ['NEO', 'ENOWOT', 'EONOTWHTERE', 'SNVEEGHEITNEIN', 'ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN']
testCases.forEach(testCase => console.log(testCase, f(testCase)))
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 38 bytes
```
Dị“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»Ḳ¤FṢŒu
L3*Ç€iṢ
```
[Try it online!](https://tio.run/##AVcAqP9qZWxsef//ROG7i@KAnMKpyK/Cv3fCtibDh2jhuYbhu4zGmCPIrsqLfsKiQ07hupNfwrvhuLLCpEbhuaLFknUKTDMqw4figqxp4bmi////Ik9ORVRXTyI "Jelly – Try It Online")
### Explanation
```
L3*Ç€iṢ    Main link. Argument: s (string)
L            Get length of s.
 3*          Raise 3 to that power. This will always be greater than n.
   Ç€        Get the name of each of the numbers using the helper link.
     iṢ      Find the position of the sorted input.
Dị“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»Ḳ¤FṢŒu    Helper link. Argument: n (number)
D                                   Get digits of n.
  “©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»            The string "one two (...) eight nine AA".
                        Ḳ           Split that string at spaces.
 ị                                  Get name of each digit in the list.
                          F         Flatten to a single string.
                           Ṣ        Sort the characters.
                            Œu      Make uppercase.
```
[Answer]
# Javascript (ES6), 221 bytes
```
s=>(m=btoa`8Ñ>Mc¾LtDáNQ!Q>HþHA7átþ4Ò`.split`+`.map(s=>RegExp(s.replace(/(.)\1*/g,c=>`(?=(.*${c[0]}){${c.length}})`))),t=0,r=0,[...s].map(c=>(t+=c,d=1,n=0,m.map((r,i)=>t.match(r)&&(d--,n=i)),d||(r=r*10+n+1,t=0))),r)
```
Example code snippet:
```
f=
s=>(m=btoa`8Ñ>Mc¾LtDáNQ
!Q>H
þHA7átþ4Ò`.split`+`.map(s=>RegExp(s.replace(/(.)\1*/g,c=>`(?=(.*${c[0]}){${c.length}})`))),t=0,r=0,[...s].map(c=>(t+=c,d=1,n=0,m.map((r,i)=>t.match(r)&&(d--,n=i)),d||(r=r*10+n+1,t=0))),r)
console.log(f("NEO"))
console.log(f("ENOWOT"))
console.log(f("EONOTWHTERE"))
console.log(f("SNVEEGHEITNEIN"))
console.log(f("ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN"))
```
[Answer]
# [Retina](https://github.com/m-ender/retina), 160 bytes
```
([ONE]{3})*([TWO]{3})*([THRE]{5})*([FOUR]{4})*([FIVE]{4})*([SIX]{3})*([SEVN]{5})*([EIGHT]{5})*([NIE]{4})*
$#1$*1$#2$*2$#3$*3$#4$*4$#5$*5$#6$*6$#7$*7$#8$*8$#9$*9
```
[Try it online!](https://tio.run/##Pcq7bsJAEIXh3q8xU8B0YJvLAxx7p5mRdoc1EqKgSJEmRZQO5dmdC5juP0ff59vX@8dtnlcXN1zv7fdaVpeY/JUp/979fw9@ytd792itWLroeeEF1RYOHVMsw/TJG6YNy4Zpy7Jlallapo6lY@pZeqYdy45pz7JnOrAcmI4sx3k2eAPzyaOBm8eUAhlNsQqMCRoGtT/hUwA5RT75gKrDWYuhokQaFTC1Hw "Retina – Try It Online") Loosely based on @TessellatingHeckler's PowerShell answer.
[Answer]
# [Perl 5](https://www.perl.org/), 102 + 1 (-n) = 103 bytes
```
for$i(map{"[$_]{".length.'}'}ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE){$,++;print$,while(s/^$i//)}
```
[Try it online!](https://tio.run/##Dcy7CoMwFADQf5GAitdHB6fOV83QBJL4gNKWDrYGbAwqdBB/vannA47t5zF37jXNRAefp928K3ncNi8Ze/Neh8Tf/Z0zBNVyUJVAhILXAgraIEjagcQGGSAtKwWMMgw3AlF0trM2K4HvoMc@WNI70Wka7s4h47xViKJSouYFNrToqGRHIlVVUsTj@E121ZNZXHzJk@yUudj8AQ "Perl 5 – Try It Online")
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 182 bytes
```
[regex]::Replace("$args",'(?<1>[ONE]{3z2>[TWO]{3z3>[THRE]{5z4>[FOUR]{4z5>[FIVE]{4z6>[SIX]{3z7>[SVEN]{5z8>[EIGHT]{5z9>[NIE]{4})'.replace('z','})|(?<'),{$args.groups.captures[1].name})
```
[Try it online!](https://tio.run/##Lc5PC4IwGMfx9yLBHIhgan8k1mnpLhPULBg7iAw7WMpMCs3Xvrbo9uHhC7@n715CDjfRtkoxKRrx5lGUib6tamFbq0o2g@UA@3jwEEsp5rM/rRErLqmRr5Vk@hhOAWKn9JzxOZhCTVJiww1iObmadKtVYmrSHWKYxElhvEeMEpMuELjyPwsm4IAFfvQqgM78e8JtZDf2g1tX/XOUYmAedx/VXSxQKZXTEuM4waSgmNAv "PowerShell – Try It Online")
Ungolfed but not working code:
```
[System.Text.RegularExpressions.Regex]::Replace("$args",
    '(?<1>[ONE]{3})       
    |(?<2>[TWO]{3})
    |(?<3>[THRE]{5})
    |(?<4>[FOUR]{4})
    |(?<5>[FIVE]{4})
    |(?<6>[SIX]{3})
    |(?<7>[SVEN]{5})
    |(?<8>[EIGHT]{5})
    |(?<9>[NIE]{4})'
    ,{$args.groups.captures[1].name}
)
```
e.g. `(?<3>[THRE]{5})` matches the character class `THRE`, so it can match them out of order, and has to match any of these characters five times next to each other, and the capture group is named '3' to map names with numbers.
Rudimentary compression by swapping the repeating text `})|(?<` for a `z`. 
[Answer]
## C++, ~~296~~, 288 bytes
Short Version:
```
#define T string
using namespace std;T N[]={"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE"};T Q(T S){T R="";for(int i=0;i<9;i++){do{if(S.find(N[i])!=T::npos){S.erase(S.find(N[i]),N[i].size());R+=to_string(i+1);}}while(next_permutation(N[i].begin(),N[i].end()));}return R;}
```
Full Version:
```
#define T string
using namespace std;
T N[]={"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE"};
T Q(T S)
{
    T R="";
    for(int i=0;i<9;i++)                             //for all possible                             
                                                     //codewords (ONE,TWO...NINE)   
    {
        do
        {   
            if(S.find(N[i])!=T::npos)                //if found in encrypted word
            {
                S.erase(S.find(N[i]),N[i].size());  //erase it from the word
                R+=to_string(i+1);                  //save integer to the result string
            }
                                                    //check next permuation of codeword  
        } while(next_permutation(N[i].begin(),N[i].end())); 
    }                                                   
    return R;
}
```
[Try ONLINE!](https://tio.run/##VVFNb4MwDD0nvyJjFxBdtR1XoLds5QIaZO2kqaoYpF2kNkEhaB9Vf3tnw6StSvSMzcuTn1237c2urs/XStf7vpEsVqZzVlaHOf2rVfudscq9XxSBpvRufr5u5FZpyQQbK7TvAJmuDrJrq1pCuYmoYNnrOjl6eca9iSdWOeKi4Jg95M8FhnSJWZm@IPIlzyDy9HEhIGYpPDxFFISefMHKgB4pEaxIPC@iZGusr7RjKrmNVHwfqTAMKAEGaQzAkQAQtfXLKbTa@NmrWgdXiZjNdGu6AH8il5ByKm3VyQveBHHaqW/pB0E00IowcWYz2vVVeDeWTwCnj3e1l76Wn27TSnvoXeWU0YPS9E3ulPZ/BSXoB4MgvKPEStdbzYqIns7o5FAhFU2CNzaaYwm7jSDE7B7CYJF0xrpLdfZPHuZFxjZZx3Vtv1onG5DxMp7jROEA5rgAnD58LvlD@pKWcCER@UpwXiyGJfASN4KKtekdi2NYxJ9ogI3/AA) 
**Edit:**  
1) 200->296 bytes, for including namespace and definition of N in the count, as suggested by orlp
2) 296->288, for using macro, thanks to Zacharý
[Answer]
# Ruby, ~~138~~ ~~114~~ 110 bytes
```
gsub(/#{"3ONE3TWO5THRE4FOUR4FIVE3SIX5SEVN5EIGHT4NIE".gsub(/(.)(\D+)/,'([\2]{\1})|')}/){(1..9).find{|i|$~[i]}}
```
Byte count includes 1 byte for the `-p` option.
### What?
This:
```
/#{"3ONE3TWO5THRE4FOUR4FIVE3SIX5SEVN5EIGHT4NIE".gsub(/(.)(\D+)/,'([\2]{\1})|')}/
```
is a regex literal which, through string interpolation, evaluates to:
```
/([ONE]{3})|([TWO]{3})|([THRE]{5})|([FOUR]{4})|([FIVE]{4})|([SIX]{3})|([SEVN]{5})|([EIGHT]{5})|([NIE]{4})|/
```
If we assign that to `regex`, the rest of the code is somewhat easy to grasp: Each match in the input is substituted with the number of the capturing group, extracted from the magical variable `$~` which contains the current match data:
```
gsub(regex){(1..9).find{|i|$~[i]}}
```
[Try it online!](https://tio.run/##JcyxTsMwFEbhPY9RkGqr4KgkGdj7J/Zyr2TfxpWaLhUqytJWlA4oCY@OCWL/zvm4H79Ser/djyp/GBYFEwqJXIn1KGve@rJ2LYrgdlVASxVcY6Ukh4X5j5TRqtusdP60VPvu5TB060mPSz3lelBrY161OfXnt2Hsx8fvfX@YppQInIE4smRgYolW4JEFaoHGwgnB0Z/gKIC34rdco3X1zgVCiyC2cQDNiBjzRmYY2c5Wfi7Xz/5yvqXn6y8 "Ruby – Try It Online")
[Answer]
# Java 8, ~~198~~ 256 bytes
```
s->{String r="",x=r;for(String n:"ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE".split(" ")){for(char c:n.toCharArray())x+="(?=.*"+c+")";x+="["+n+"]{"+n.length()+"}x";}for(int i=0,q;i<9;)for(q=(s+" ").split(x.split("x")[i++]).length-1;q-->0;)r+=i;return r;}
```
+58 bytes.. due to regex of the previous version not working properly (it was also matching "EEE";"EEN";etc.)
**Explanation:**
[Try it here.](https://tio.run/##jZHBTuMwEIbvPMXIpxiTiD0uJqDVatrksLaUmAap6iGEAGZTp3VcCKry7MWB9EwlW54Zz/zj@fxavpVhu6nN6@P/Q9WUXQf/Sm32ZwDauNo@lVUNYnQBcme1eYYqmIyOch8f/PZLgIEYDl14s5@ubUzIRR9b/tTaY4m5IlIgqEKCSjJEmMm7DGbpAiFP7yHHBQrAdJ4oEKlAEnWbRruAAKF0P@pUL6WF6spErv3rzT/Wlh8BpT2LSXAbR@eEVYxQwsfAkjDDyGrvj6ipzbN7CSgjQ0/4MEr5@UDHlxdbrq9/czqGtnHQsbHZ1Lc/9u8JXWrGVnQSCn/xbRjeXHJqWay5rd3OGrB8OPBvHJvdQ6Mr6Fzp/PHW6kdYe64Th@UKSvoNdaQNa4/O1O9fTvBF1dP@6Fy9jtqdiza@xjUmWEcmqgIiUHocP2WhkIVUpyRKIVWRKMzwhOxcLBDnCaZKYCpOe4csFGKWqOxOznCRzu7TXPifzlUyTxHFSTJCoh9HySLxUsexhrPh8Ak)
```
s->{                     // Method with String as parameter and return-type
  String r="",           //  Result-String
         x=r;            //  Regex-String
  for(String n:"ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE".split(" ")){
                         //  Loop (1) from "ONE" through "NINE":
    for(char c:n.toCharArray())
                         //   Inner loop (2) over the characters of this String
      x+="(?=.*"+c+")";  //    Append regex-group `(?=\w*c)` where `c` is the capital character
                         //   End of inner loop (2) (implicit / single-line body)
    x+="["+n+"]{"+n.length()+"}x";
                         //   Append regex part `[s]{n}` where `s` is the String, and `n` is the length
  }                      //  End of loop (1)
  // The regex now looks like this, which we can split on "x":
  // (?=.*O)(?=.*N)(?=.*E)[ONE]{3}x(?=.*T)(?=.*W)(?=.*O)[TWO]{3}x(?=.*T)(?=.*H)(?=.*R)(?=.*E)(?=.*E)[THREE]{5}x(?=.*F)(?=.*O)(?=.*U)(?=.*R)[FOUR]{4}x(?=.*F)(?=.*I)(?=.*V)(?=.*E)[FIVE]{4}x(?=.*S)(?=.*I)(?=.*X)[SIX]{3}x(?=.*S)(?=.*E)(?=.*V)(?=.*E)(?=.*N)[SEVEN]{5}x(?=.*E)(?=.*I)(?=.*G)(?=.*H)(?=.*T)[EIGHT]{5}x(?=.*N)(?=.*I)(?=.*N)(?=.*E)[NINE]{4}x
  for(int i=0,q;i<9;)    //  Loop (3) from 0 through 9 (exclusive)
    for(q=(s+" ").split(x.split("x")[i++]).length-1;
                         //   Split the input on the current regex-part,
                         //   and save the length - 1 in `q`
        q-->0;           //   Inner loop (4) over `q`
      r+=i               //    And append the result-String with the current index (+1)
    );                   //   End of inner loop (4)
                         //  End of loop (3) (implicit / single-line body)
  return r;              //  Return the result-String
}                        // End of method
```
[Answer]
# [Java (OpenJDK 8)](http://openjdk.java.net/), 181 bytes
```
s->{String x="",r;for(int i=0,l;i<9;)for(r="ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".split(",")[i++],l=r.length();s.matches("["+r+"]{"+l+"}.*");s=s.substring(l))x+=i;return x;}
```
[Try it online!](https://tio.run/##jVHLbsMgELz3KxAnXBPUa@W6t03MoSDZJK4U5eC4bkqLSQQkTRX521Py6LmRWMHuDqOd2c9m14zWm85@vn0dW9N4j14abQ93CGkbOvfetB0SpxShKjhtV6gl14dPslgfYsQjkEU5OvrR8@Ha3ucYU5e9rx2JVEjnD9Rk@ukxS04ll2MpgKpaUlWUAHQspyUd8xnQir/SCmYgKPBJoajgAjDzG6MDwRQnc52mC2pyx0xnV@GDJJlnfRPaj84TPMepS/HigFOT4oHd49jNPfPbpT/PRUyS7NNcZ64LW2fRPhuO2UXDZrs0ukU@NCFeu7V@Q30046p3vkBNcnHiZBHqo17bfZ8TcrYiWvTjQ9ez9TawTfwTjCU9s6wlWIDEyb8oELKW6hagFFLVhYISbkBXYgYwKYArAVzcNoesFUBZqHIqxzDj41deibiUShUTDiBuohESohwl6yJS/cka7objLw "Java (OpenJDK 8) – Try It Online")
I took the liberty to reuse [Kevin Cruyssen's TIO template](https://codegolf.stackexchange.com/a/132077/16236). Hope you don't mind ;)
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), ~~36~~ 31 bytes
```
‘€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘#vyœN>UvyX:
```
[Try it online!](https://tio.run/##AVQAq/8wNWFiMWX//@KAmOKCrMK14oCa4oCi4oCew63igKDDrMuGw4jFksWhw6/Cv8W4wq/CpcWg4oCYI3Z5xZNOPlV2eVg6//9PRU5UT1dURUVSSEZPUlU "05AB1E – Try It Online")
---
View it ran with debug: [TIO With Debug](https://tio.run/##AVcAqP8wNWFiMWX//@KAmOKCrMK14oCa4oCi4oCew63igKDDrMuGw4jFksWhw6/Cv8W4wq/CpcWg4oCYI861xZN9dnlOPlV2eVg6//9PRU5UT1dURUVSSEZPUlU)
```
‘€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘# | Push ['ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE']
vyœ                   | For each list of permutations of that word...
   N>U                | Push index + 1 into register X.          
      vyX:            | Replace each permutation with X.
```
[Answer]
# [Python 3](https://docs.python.org/3/), ~~238~~ 236 bytes
```
def f(s):
 e=''
 while len(s):
  for i in range(9):
   for r in[''.join(p)for p in permutations('ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split()[i])]: 
    if s[:len(r)]==r:e+=str(i+1);s=s[len(r):]
 return e
from itertools import*
```
[Try it online!](https://tio.run/##jc89a8MwEAbg3b/iyGKpKYHSqS4ez7YWCWzFCRgPgciNii0JSaH017uxEyh06nTw3Mt9uO94seZ1ns9qgIEEmiWg8jRN4OuiRwWjMneEwXrQoA34k/lQ5G3FVW9uujTdfVptiKMLuSXolJ@u8RS1NYGkgiPIgwBZ1YhQiH0NBWsRGnaEBlvkgKysJHDGMd0FN@pIaKd72mewbAI9QOiy5SBP@zz3mdrmIXqity/0PeShu7eyPgGv4tUbUMng7QQ6Kh@tHQPoyVkfn2bntYlkw1Fsnod7pTR5aMNbxLJCJjkyvgb@0G8WuRAHiVhXst6LAltWHFnDb@80sioZIn9M@FeQ0vkH "Python 3 – Try It Online")
---
Brute-force solution, doesn't take advantage non-decreasingness of digits.
---
Thanks to @Mr. Xcoder for saving 2 bytes!
[Answer]
# PHP, 141 bytes
```
for($a=count_chars($argn);$c=ord($s[++$p]?:$s=[OWU,W,HG,U,FU,X,SX,G,N17.$p=0][$i-print str_repeat($i++,$x)]);)$x=$a[$i+48]+=($p?-1:1)*$a[$c];
```
older version, **151 bytes**:
```
for($a=count_chars($argn,1);$s=[OWU,W,HG,U,FU,X,SX,G,N17][+$i++];print str_repeat($i,$a[$i+48]))for($p=0;$c=ord($s[$p]);)$a[$i+48]+=($p++?-1:1)*$a[$c];
```
loops through the digits from 1 to 9, counting unique characters in the word and subtracting non-unique characters´ counts, printing the digit on the go.  
Although it is printing on the go, the digit counts must be stored for the `9` case to work.
Run as pipe with `-nR` or [try it online](http://sandbox.onlinephpfunctions.com/code/d55e59c0dadd323e1abf1b87ee1beab3eda81d84).
It would save 4 more bytes to store the digit counts in `$a[$i]` instead of `$a[$i+48]` and use ASCII `1` and `7` (in quotes) instead of the digit characters themselves.
**breakdown**
```
for(
    $a=count_chars($argn,1);                # count character occurences in input
    $s=[OWU,W,HG,U,FU,X,SX,G,N17][+$i++];   # loop through digit names
    print str_repeat($i,$a[$i+48])              # print digit repeatedly
)
    for($p=0;$c=ord($s[$p]);)                   # loop through name
        $a[$i+48]+=                                 # add to digit count
        ($p++?-1:1)*                                # (add first, subtract other)
        $a[$c];                                     # character occurences
```
`ONE` is not the only word with an `O`, so it needs to subtract the counts for `W` (only appearing in `TWO`) and `U` (only appearing in `FOUR`) and so on.  
`NINE` is special, because there is no way to just subtract if I used the letters (that would require `I-X-G-F+U` or `N-O-S+W+U+X`), so I use the digit counts instead.
# PHP, 160 bytes
```
$a=count_chars($argn);foreach([W2O,U4FOR,X6SI,G8I,F5I,O1,R3,S7,I9]as$s)for(${$s[$p=1]}+=$n=$a[ord($s)];$c=ord($s[++$p]);)$a[$c]-=$n;while($$i--?print$i:$i++<9);
```
assumes all upper case input; characters may be scrambled all over.  
Run as pipe with `-nR` or [try it online](http://sandbox.onlinephpfunctions.com/code/07454a4d490a2e124e2a9af361b5ba4bf9153e1f).
**explanation**
loops through the digit words, counting their unique characters´ occurences in the input and in the process reducing the count of other characters.
"Other characters" *could* mean all other characters in the word; but only considering those that will be needed later saved 19 bytes.
Transforming the `str_repeat` loop to a combined loop saved 5 bytes.
And using variable variables for the digit count saved another 8.
**breakdown**
```
$a=count_chars($argn);                              # count character occurences in input
foreach([W2O,U4FOR,X6SI,G8I,F5I,O1,R3,S7,I9]as$s)   # loop through digit names
    for(${$s[$p=1]}+=                                   # 2. add to digits count
        $n=$a[ord($s)];                                 # 1. get count of unique character
        $c=ord($s[++$p]);)                              # 3. loop through other characters
        $a[$c]-=$n;                                         # reduce character count
while(
    $$i--?print$i                                       # print digit repeatedly
    :$i++<9);                                       # loop through digits
```
]