24
\$\begingroup\$

In the most common contemporary graphical desktop interfaces, when you perform double-click in a text, the word around your cursor in the text will be selected.

For example, let | be your cursor in abc de|f ghi. Then, when you double click, the substring def will be selected.

Input/Output

You receive two inputs:

  • a string and
  • an integer. Your task is to return the word‐substring of the string around the index specified by the integer.

Your cursor can be right before or right after the character in the string at the index specified. If you use right before, please specify in your answer.

Specifications

  • The index is guaranteed to be inside a word, so no edge cases like abc |def ghi or abc def| ghi.
  • The string will only contain printable ASCII characters (from U+0020 to U+007E).
  • The word word is defined by the regex (?<!\w)\w+(?!\w), where \w is defined by [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_], or “alphanumeric characters in ASCII including underscore”.
  • The index can be either 1‑based or 0‑based. If you use are 0‑based index, please specify it in your answer.

Test cases

The cursor position visualization is for demonstration purpose only; it is not a required output. The cursor is indicated right after the index specified. Here, the sample string indices are 1‑based.

sample index visualization output
abc def 2 ab|c def abc
abc def 5 abc d|ef def
abc abc 2 ab|c abc abc
ab cd ef 4 ab c|d ef cd
ab cd 6 ab c|d cd
ab!cd 1 a|b!cd ab

) This feature has more complicated properties, but they are not required to be implemented for this challenge.

\$\endgroup\$
5
  • 2
    \$\begingroup\$ Can the string contain newlines? \$\endgroup\$
    – orlp
    Jul 18, 2016 at 15:04
  • \$\begingroup\$ @orlp The challenge was edited to restrict the input to printable ASCII so the input will not contain newlines. \$\endgroup\$ Jul 18, 2016 at 15:15
  • \$\begingroup\$ Your testcases do not contain any other delimiters than spaces. What about a word like we're? \$\endgroup\$
    – orlp
    Jul 18, 2016 at 15:27
  • 2
    \$\begingroup\$ What should "ab...cd", 3 return? \$\endgroup\$
    – Titus
    Jul 18, 2016 at 16:22
  • 5
    \$\begingroup\$ @Titus "The index is guaranteed to be inside a word" \$\endgroup\$ Jul 18, 2016 at 16:26

27 Answers 27

9
\$\begingroup\$

V, 10, 9 7 bytes

À|diwVp

Try it online!

This answer uses 1-based indexing.

This could be shorter if we do exactly what the title says: "Select the word around the given index in a string". We could do

À|viw

Which literally selects the word, but unfortunately doesn't change the output at all. So we need a little workaround to make it work by cutting it into a register, deleting the rest of the text, then pasting the register back in.

Explanation:

À|          " Jump the position of argument 1
  diw       " (d)elete (i)nside this (w)ord.
     V      " Select this line
      p     " And replace it with the word we just deleted
\$\endgroup\$
5
\$\begingroup\$

C, 104 bytes

p[99];i,d;main(l){for(scanf("%d",&i);scanf("%[^a-zA-Z0-9_]%[a-zA-Z0-9_]%n",&d,&p,&l),i>l;i-=l);puts(p);}

Expects the input on stdin to be the 0-based index followed by one space or newline, followed by the string. Maximal length for a word is 99 characters. E.g.:

2 abc def
\$\endgroup\$
6
  • \$\begingroup\$ It's really cool to see C and perl tied on a string based challenge. :D \$\endgroup\$
    – DJMcMayhem
    Jul 18, 2016 at 15:26
  • \$\begingroup\$ Can the input string have longer than 100 characters? \$\endgroup\$
    – Leaky Nun
    Jul 18, 2016 at 15:27
  • \$\begingroup\$ @LeakyNun Yes, but one word can not be longer than 100 characters. \$\endgroup\$
    – orlp
    Jul 18, 2016 at 15:27
  • \$\begingroup\$ Do you feel like putting that requirement inside your answer? \$\endgroup\$
    – Leaky Nun
    Jul 18, 2016 at 15:28
  • \$\begingroup\$ @DrGreenEggsandIronMan Too bad I had to fix my answer because it was delimited on whitespace :( \$\endgroup\$
    – orlp
    Jul 18, 2016 at 15:36
4
\$\begingroup\$

C (gcc), 94 bytes

f(n,p)char*p;{for(p+=n-1;isalnum(*p)|*p==95&&n--;--p);for(;isalnum(*++p)|*p==95;putchar(*p));}

Zero-indexed, defines a function taking the index, then the string.

\$\endgroup\$
6
  • \$\begingroup\$ I think isalnum(*++p)|*p==95 is undefined behavior. \$\endgroup\$
    – owacoder
    Jul 18, 2016 at 17:06
  • \$\begingroup\$ @owacoder It is, but what matters is that gcc spits out an executable that works. *++p^95?isalnum(*p):1 is one byte longer, but works on every compiler. \$\endgroup\$
    – orlp
    Jul 18, 2016 at 17:07
  • \$\begingroup\$ I assume the leading space is a typo? Also, here's a lazy IDEone link. \$\endgroup\$ Jul 18, 2016 at 17:11
  • \$\begingroup\$ isalnum(*++p)||*p==95 also works, for an added one byte. \$\endgroup\$
    – owacoder
    Jul 18, 2016 at 17:12
  • \$\begingroup\$ @FryAmTheEggman Yes it is, fixed now. \$\endgroup\$
    – orlp
    Jul 18, 2016 at 17:13
3
\$\begingroup\$

Retina, 22

(1)+¶(?<-1>.)*\b|\W.+

Try it online! or verify all test cases. The regular program takes the cursor position in unary followed by a newline and then the string. The test suite has additional code to run in per line mode, and uses a \ as a delimiter, and it uses decimal, for convenience.

Uses balancing groups to find the cursor position, then backtracks up to a word boundary. Deletes the text up to the word, and then after the word.

\$\endgroup\$
0
3
\$\begingroup\$

Pyth, 16 bytes

+e=:.<+QbE"\W"3h

       Q            first input (string)
      + b           plus newline
    .<   E          rotate left by second input (number)
   :      "\W"3     split on regex \W, non-word characters
  =                 assign to Q
 e                  last element
+              hQ   plus first element

Try it online

\$\endgroup\$
3
\$\begingroup\$

Ruby, 41 31 bytes

Try it online!

-10 bytes from @MartinEnder

->s,i{s[/\w*(?<=^.{#{i}})\w*/]}
\$\endgroup\$
0
3
\$\begingroup\$

Python 2, 70 66 bytes

import re
f=lambda x,y,r=re.split:r('\W',x[:y])[-1]+r('\W',x[y:])[0]

Splits the string by non-word separators, once on the original string up to the cursor index, then on the string beginning at the cursor index. Returns the last element of the left split plus the first element of the right split. Thanks to Leaky Nun for saving 4 bytes!

\$\endgroup\$
1
  • \$\begingroup\$ For non-recursive lambdas, you can omit the f= to 'save' two more bytes. \$\endgroup\$
    – movatica
    Mar 15 at 7:00
3
\$\begingroup\$

JavaScript (V8), 44 bytes

(i,x)=>RegExp(`\\w*(?<=.{${i}})`).exec(x)[0]

Try it online!

This is longer than an existing JS solution, but I don't actually understand the approach it uses, and I wrote this prior to seeing that solution. Hopefully this is different enough to be interesting :P

Code explanation, so the same fate is not befallen upon ye

(i,x)=>                                 take i (number) and x (string)
       RegExp(`...${i}...`)             construct a regex with i in it
                           .exec(x)[0]  return the first result of that regex on the string

\w*(?<=.{i}) constructed regex
\w*          match an entire word
   (?<=    ) if the end of the word comes after
       .{i}  at least i characters
\$\endgroup\$
1
  • \$\begingroup\$ 43 bytes if you curry but who really cares \$\endgroup\$ Oct 6, 2022 at 13:50
2
\$\begingroup\$

C, 115 bytes

Function f() requires the string and index (1-indexed) as parameters and prints the result to stdout. Cursor should be after the specified character.

f(char*p,int n){char*s=p+n;for(;s>=p&&isalnum(*s)+(*s==95);--s);for(p=s+1;*p&&isalnum(*p)+(*p==95);putchar(*p++));}
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 57 bytes

f=(s,n)=>s.slice(0,n).match(/\w*$/)+s.slice(n).match(/\w*/)

Simply slices the string at the cursor point (which is before the 0-indexed character, which works out the same as after the 1-indexed character), then extracts and concatenates the adjacent word fragments. Even returns a sensible result when the cursor is at the start, end, or nowhere near a word.

\$\endgroup\$
3
  • \$\begingroup\$ Do you need the * in the last regex? \$\endgroup\$ Jul 18, 2016 at 17:31
  • \$\begingroup\$ @CharlieWynn Yes, otherwise the second testcase would only return de. \$\endgroup\$
    – Neil
    Jul 18, 2016 at 17:37
  • \$\begingroup\$ whoops, got unlucky with the tests I ran \$\endgroup\$ Jul 18, 2016 at 17:39
2
\$\begingroup\$

Java 8, 86 78 bytes

(s,p)->{for(String t:s.split("\\W"))if((p-=t.length()+1)<0)return t;return"";}

Ungolfed with test cases:

class Indexer {
    public static String f(String s, int p) {
        for(String t : s.split("\\W"))
            if((p -= t.length()+1) < 0)
                return t;
        return "";
    }

    public static void main(String[] args) {
        System.out.println(f("abc def",2));
        System.out.println(f("abc def",5));
        System.out.println(f("abc abc",2));
        System.out.println(f("ab cd ef",4));
        System.out.println(f("ab   cd",6));
        System.out.println(f("ab!cd",1));
    }
}

Splits the string by non-alphanumeric characters, then keeps subtracting the length of each substring, plus 1, from the specified position, until it becomes negative. Since any repeating non-alphanumerics get represented as empty string, the subtraction logic is significantly easier.

This code isn't extensively tested, so I'd like to see if someone can break this. Also, considering that this is Java code, how is this not the longest answer here? :P

\$\endgroup\$
1
  • \$\begingroup\$ I know it's been almost three years, but (s,p)-> can be s->p-> by using a currying lambda expression (i.e. java.util.function.Function<String, java.util.function.Function<String, String>> f). In addition, String could be var now if switched to Java 10, although that wasn't available at the time of course. Regardless, nice answer. I see I've already updated it somewhere in the past. :) \$\endgroup\$ Mar 15, 2019 at 10:40
2
\$\begingroup\$

Pyke, 19 bytes

#Q;cjmli<i+s)lttjR@

Try it here!

Uses Q; as a no-op to make sure the first input is placed correctly

#          )   -  first where
   c           -       input.split()
    ml         -      map(len, ^)
      i<       -     ^[:i]
        i+     -    ^+[i]
          s    -   sum(^)
            lt - len(^)-2
\$\endgroup\$
4
  • \$\begingroup\$ I'm having a 504 error when I click your link. \$\endgroup\$
    – Leaky Nun
    Jul 18, 2016 at 17:32
  • \$\begingroup\$ @LeakyNun Yeah, I killed it by accident whilst writing which is why I had the localhost link, it'll come back \$\endgroup\$
    – Blue
    Jul 18, 2016 at 17:36
  • \$\begingroup\$ Try it here! \$\endgroup\$
    – Leaky Nun
    Jul 19, 2016 at 7:56
  • 1
    \$\begingroup\$ Your program seems to be outputting N where the Nth word is the one selected, but we need the full word \$\endgroup\$
    – Value Ink
    Jul 19, 2016 at 9:33
2
\$\begingroup\$

Ruby, 30 bytes

->s,n{s[/.{#{n}}\w+/][/\w+$/]}

Try it online!

A different approach, only 1 byte shorter and 3 years later. Why not?

\$\endgroup\$
1
\$\begingroup\$

Clojure, 92 bytes

(fn[x k](let[[u i](map #(re-seq #"\w+"(apply str %))(split-at k x))](str(last u)(nth i 0))))

First, splits input string at position k into two strings. Then for these strings find occurrences of "\w+" and return them as list. Then concatenate the last element of first list and the first element of second list.

See it online: https://ideone.com/Dk2FIs

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 52 bytes

(s,n)=>RegExp(`^.{0,${n}}(\\W+|^)(\\w+)`).exec(s)[2]

const F = (s,n) => RegExp(`^.{0,${n}}(\\W+|^)(\\w+)`).exec(s)[2]

class Test extends React.Component {
    constructor(props) {
        super(props);
        const input = props.input || '';
        const index = props.index || 0;
        this.state = {
            input,
            index,
            valid: /\w/.test(input),
        };
    }
    onInput = () => {
        const input = this.refs.input.value;
        const index = Math.min(+this.refs.index.value, input.length);
        this.setState({
            input,
            index,
            valid: /\w/.test(input),
        });
    }
    render() {
        const {input, index, valid} = this.state;
        return (
            <tr>
                <td>{ this.props.children }</td>
                <td>
                    <input ref="input" type="text" onInput={this.onInput} value={input} />
                    <input ref="index" type="number" onInput={this.onInput} min="1" max={input.length} value={index} />
                </td> 
                {valid && [
                    <td>{F(input, index)}</td>,
                    <td><pre>{input.slice(0, index)}|{input.slice(index)}</pre></td>,
                ]}
            </tr>
        );
    }
}

class TestList extends React.Component {
    constructor(props) {
        super(props);
        this.tid = 0;
        this.state = {
            tests: (props.tests || []).map(test => Object.assign({
                key: this.tid++
            }, test)),
        };
    }
    addTest = () => {
        this.setState({
            tests: [...this.state.tests, { key: this.tid++ }],
        });
    }
    removeTest = key => {
        this.setState({
            tests: this.state.tests.filter(test => test.key !== key),
        });
    }
    
    render() {
        return (
            <div>
                <table>
                    <thead>
                        <th/>
                        <th>Test</th>
                        <th>Output</th>
                        <th>Diagram</th>
                    </thead>
                    <tbody>
                        {
                            this.state.tests.map(test => (
                                <Test key={test.key} input={test.input} index={test.index}>
                                    <button onClick={() => this.removeTest(test.key)} style={{
                                        verticalAlign: 'middle',
                                    }}>-</button>
                                </Test>
                            ))
                        }
                    </tbody>
                    <tfoot>
                        <td/>
                        <td>
                            <button onClick={this.addTest} style={{
                                width: '100%',
                            }}>Add test case</button>
                        </td>
                    </tfoot>
                </table>
            </div>
        );
    }
}

ReactDOM.render(<TestList tests={[
    { input: 'abc def', index: 2 },
    { input: 'abc def', index: 5 },
    { input: 'abc abc', index: 2 },
    { input: 'ab cd ef', index: 4 },
    { input: 'ab   cd', index: 6 },
    { input: 'ab!cd', index: 1 },
]} />, document.body);
input[type="number"] {
  width: 3em;
}
table {
  border-spacing: 0.5em 0;
  border-collapse: separate;
  margin: 0 -0.5em ;
}
td, input {
    font-family: monospace;
}
th {
  text-align: left;
}
tbody {
  padding: 1em 0;
}
pre {
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

\$\endgroup\$
1
  • \$\begingroup\$ Why (\\W+|^) not (\\W|^) \$\endgroup\$
    – l4m2
    Dec 14, 2017 at 14:42
1
\$\begingroup\$

Lua, 71 67 Bytes

Woohoo, Lua isn't the longest solution! Still one byte behind python, but don't know how to golf this down. Indexes are 1-based.

Thanks to @LeakyNun reminding me the existence of string.match, saved 4 bytes

g,h=...print(g:sub(1,h):match"[%a_]*$"..g:sub(h+1):match("[%a_]+"))

Old 71

Note: the explanations are still based on this one, because it also applies to the new one, but contains some extra informations on gmatch

g,h=...print(g:sub(1,h):gmatch"[%a_]*$"()..g:sub(h+1):gmatch"[%a_]*"())

Explanation

First, we unpack the arguments into g and h because they are shorter than arg[x]

g,h=...

Then, we construct our output, which is the concatanation of the part before the cursor and after it.

The first part of the string is

g:sub(1,h)

We want to find the word at the end of this one, so we use the function string.gmatch

:gmatch"[%a_]*$"

This pattern match 0..n times the character set of alphabet+underscore at the end of the string. gmatch returns an iterator on its list of match in the form of a function (using the principle of closure), so we execute it once to get the first part of our word

g:sub(1,h):gmatch"[%a_]*$"()

We get the second part of our word by the same way

g:sub(h+1):gmatch"[%a_]*"())

The only difference being we don't have to specify we want to match at the start of the string (using [^%a_]*), as it will be the match returned by the iterator when it's called the first time.

\$\endgroup\$
8
  • \$\begingroup\$ g:sub(h+1):match"^[%a_]*"? \$\endgroup\$
    – Leaky Nun
    Jul 19, 2016 at 7:50
  • \$\begingroup\$ @LeakyNun totally forgot the existence of match \o/ saves lot of bytes, thanks \$\endgroup\$
    – Katenkyo
    Jul 19, 2016 at 7:52
  • \$\begingroup\$ @LeakyNun both indices and indexes are correct ^^ \$\endgroup\$
    – Katenkyo
    Jul 19, 2016 at 7:57
  • \$\begingroup\$ I don't care, still -1 for "indexes". \$\endgroup\$
    – Leaky Nun
    Jul 19, 2016 at 8:01
  • \$\begingroup\$ Why don't we need the ^ anchor? \$\endgroup\$
    – Leaky Nun
    Jul 19, 2016 at 8:02
1
\$\begingroup\$

JavaScript (ES 6), 4342 Bytes

s=>n=>s.replace(/\w*/g,(x,y)=>y<n?s=x:0)&&s

JavaScript (ES 3), 65 Bytes

function(s,n){s.replace(/\w*/g,function(x,y){y<n?s=x:0});alert(s)}
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 14 bytes

ð«._DžjмS¡Á2£J

Port of @AndersKaseorg's Pyth answer.

1-indexed like the challenge test cases.

Try it online or verify all test cases.

Explanation:

ð«              # Append a space to the (implicit) input-String
  ._            # Rotate this string the (implicit) input-integer amount of times
                #  towards the left
     D          # Duplicate this string
      žjм       # Remove [a-zA-Z0-9_] from the string
         S¡     # Split the rotated string by each of the remaining characters
           Á    # Rotate the resulting list once towards the right
            2£J # And only leave the first two items, joined together
                # (which is output implicitly)
\$\endgroup\$
1
\$\begingroup\$

Perl 6, 34 bytes

->\b{&{first *.to>b,m:g/<<\w+>>/}}

Try it online!

Anonymous codeblock that takes input curried, like f(n)(string).

Explanation:

->\b{                            }   # Anonymous code block that takes a number
     &{                         }    # And returns another code block that
       first       ,m:g/<<\w+>>/     # Finds the first word in the input
             *.to>b                  # Where the start is after the number
\$\endgroup\$
1
\$\begingroup\$

APL(NARS), 58 chars, 116 bytes

{m←⎕A,⎕a,⎕D,'_'⋄↑v⊂⍨m∊⍨v←⍵↓⍨¯1+⍵{⍵≤1:⍵⋄m∊⍨⍵⊃⍺:⍺∇⍵-1⋄⍵+1}⍺}

⍵{⍵≤1:⍵⋄m∊⍨⍵⊃⍺:⍺∇⍵-1⋄⍵+1}⍺ find where start the string...How to use and test:

  f←{m←⎕A,⎕a,⎕D,'_'⋄↑v⊂⍨m∊⍨v←⍵↓⍨¯1+⍵{⍵≤1:⍵⋄m∊⍨⍵⊃⍺:⍺∇⍵-1⋄⍵+1}⍺}
  2 f 'abc def'
abc
  5 f 'abc def'
def
  2 f 'abc abc'
abc
  4 f 'ab cd ef'
cd
  1 f 'ab!cd'
ab
  6 f 'ab   cd'
cd 
\$\endgroup\$
1
\$\begingroup\$

Jelly, 12 bytes

Żṙe€ØW¬œpƊ.ị

Try it online!

Port of Anders Kaseorg's Pyth answer.

Ż               Prepend a zero as a buffer between the first and last words,
 ṙ              then rotate left by the index.
       œpƊ      Partition that result around
   €  ¬         elements which are not
  e ØW          word characters,
          .ị    then take the last and first slices
                and smash-print them together.

Original:

Jelly, 14 bytes

xðe€ØW¬Ä÷Ɗ=ị@¥

Try it online!

  eۯW            For each element, is it a word character?
       Ä          Take the cumulative sum
      ¬           of the negations
        ÷Ɗ        and divide by the original Booleans.
          =       For each value in the result, is it equal to
           ị@¥    the one at the index?
xð                Filter the string to truthy positions.
\$\endgroup\$
0
\$\begingroup\$

MATL, 16 15 bytes

'\w+'5B#XXi>)1)

Cursor is 1-indexed and after the character (as in the test cases).

Try it online! Or verify all test cases.

'\w+'    % Push string to be used as regex pattern
5B#XX    % Take input string implicitly. Apply regex. Push matches and ending indices
i>       % Take input number. Compare with obtained ending indices. Gives true for
         % ending indices that exceed the input number
)        % Use as logical index to select the corresponding matches
1)       % Select the first match. Implicitly display
\$\endgroup\$
0
\$\begingroup\$

PowerShell v3+, 103 101 bytes

param($a,$n)for(;$n[++$a]-match'\w'){}$i=$a--;for(;$n[--$a]-match'\w'-and$a-ge0){}-join$n[++$a..--$i]

Kind of a goofy solution, but a different approach than others.

Takes input $a as the 0-based index of the string $n. Then, we find the boundaries of our word. While we've not reached the end of the string and/or we're still matching word-characters, we ++$a. Then, because of fenceposting, we set $i=$a--. Next, we crawl backwards, decrementing $a until it's either 0 or we hit a non-word-character. We then slice the input string based on those two demarcations (with some increment/decrements to account for OBOE), and -join it together to produce the result.

Examples

PS C:\Tools\Scripts\golfing> .\select-the-word-around-the-index.ps1 2 'This!test'
This

PS C:\Tools\Scripts\golfing> .\select-the-word-around-the-index.ps1 5 'This!test'
test
\$\endgroup\$
1
  • \$\begingroup\$ select-the-word-around-the-index.ps1 \$\endgroup\$
    – Leaky Nun
    Jul 19, 2016 at 17:06
0
\$\begingroup\$

PHP, 98 bytes

function f($s,$p){foreach(preg_split('#\W+#',$s,-1,4)as$m)if($m[1]+strlen($m[0])>=$p)return$m[0];}
  • splits the string by non-word-characters, remembering their position (4 == PREG_SPLIT_OFFSET_CAPTURE), loops through the words until position is reached.
  • PHP strings are 0-indexed, cursor before character, but may be before or after the word
\$\endgroup\$
0
\$\begingroup\$

Python 3, 112 140 bytes

from string import*
p='_'+printable[:62]
def f(s,h,r=''):
 while s[h]in p and h>-1:h-=1
 while h+1<len(s)and s[h]in p:h+=1;r+=s[h]
 return r

0-indexed.

Seeks backward to the first alphanumeric character from the index, then goes forward to the last alphanumeric character after the index. There's probably a smarter way to do this.

Try it

\$\endgroup\$
1
  • \$\begingroup\$ @LeakyNun _ was added, I'm not sure why I'd get an error for f('abc',1) though. \$\endgroup\$ Jul 19, 2016 at 13:30
0
\$\begingroup\$

Javascript (using external library) (168 bytes)

(n,w)=> _.From(w).Select((x,i)=>({i:i,x:x})).Split((i,v)=>v.x==" ").Where(a=>a.Min(i=>i.i)<=n-1&&a.Max(i=>i.i)>=n-2).First().Select(i=>i.x).Write("").match(/^\w*^\w*/)[0]

Link to lib:https://github.com/mvegh1/Enumerable/blob/master/linq.js

Explanation of code: Library accepts a string, which gets parsed into a char array. It gets mapped to an object storing the index and the char. The sequence is split into subsequences at every occurrence of " ". The subsequences are filtered by checking if the cursor index is contained within the min and max index of the subsequence. Then we take the first subsequence. Then we transform back to just a char array. Then we concatenate all characters with "" as the delimiter. Then we validate against word regex. Then we take the first match.

enter image description here

\$\endgroup\$
6
  • \$\begingroup\$ The word "word" is defined by the regex (?<!\w)\w+(?!\w), where \w is defined by [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_], or "alphanumeric characters in ASCII including underscore". \$\endgroup\$
    – Leaky Nun
    Jul 19, 2016 at 16:06
  • \$\begingroup\$ When I run that regex against ab!cd on regex101.com I get this: No match groups were extracted. This means that your pattern matches but there were no (capturing (groups)) in it that matched anything in the subject string. Maybe I'm making a mistake somewhere... \$\endgroup\$ Jul 19, 2016 at 16:10
  • \$\begingroup\$ Why would I need to capture anything? \$\endgroup\$
    – Leaky Nun
    Jul 19, 2016 at 16:15
  • \$\begingroup\$ I know this isnt the place to learn, but I'm saying that when I run that regex against ab!cd I don't get anything. So why would 'ab' be the correct output? \$\endgroup\$ Jul 19, 2016 at 16:20
  • 1
    \$\begingroup\$ You are invited to our chatroom to further discuss your answer. \$\endgroup\$
    – Leaky Nun
    Jul 19, 2016 at 16:22
0
\$\begingroup\$

Perl 5 -p, 35 bytes

$b=<>;($_)=/.{$b}\w+/g;($_)=/\w+$/g

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.