Mike
Mike

Reputation: 8100

Groovy string replace

I'm working on some Groovy code to take text that's meant to be a Tweet, and turn all hashtags into web-links to the Twitter hashtag. In fact, I have that code working, but it fails when there's a bare # in the text that's meant to be read as a "number sign" instead of a hashtag.

The working (except for that edge case) code is:

static replaceHashTags(input) {
    while (input.contains(/#/)) {
        input = input.replaceAll(/(.*)#(\w+)(.*)/, { all, before, hashtag, after ->
            "${before}<a href='https://twitter.com/hashtag/${hashtag}'>${hashtag}</a>${after}"
        })
    }

    input.replaceAll(/<a href='https:\/\/twitter.com\/hashtag/, '#<a href=\'https://twitter.com/hashtag')
}

Instead of breaking what is mostly-working code before I had a solution, I wrote a test class to try out my new matching code. It's failing, and I can't figure out why. Here's the test class:

class StringTest {
    def checkContains(string, expression) {
        string.contains(expression)
    }

    @Test
    void shouldTestSomethingElse() {
        assert (checkContains('This is a string', /is/)) // Passes
        assert !(checkContains('This is a string', /werigjweior/)) // Passes

        assert (checkContains('#This tweet starts with a hashtag', /#This/)) // Passes
        assert (checkContains('#This tweet starts with a hashtag', /#(\w+)/)) // Fails.
    }
}

As I said, I'm not sure why that last assert fails. What my expectation was going into this exercise was that I could simply replace while (input.contains(/#/)) { with while (input.contains(/#(\w+)/)) {...But that doesn't seem to be the case.

Upvotes: 0

Views: 842

Answers (1)

sebnukem
sebnukem

Reputation: 8313

I'm not convinced string.contains() accepts regex as argument. This works for me:

def checkContains(string, expression) {
  string =~ expression
}

assert (checkContains('This is a string', /is/))
assert !(checkContains('This is a string', /werigjweior/))
assert (checkContains('#This tweet starts with a hashtag', /#This/))
assert (checkContains('#This tweet starts with a hashtag', /#(\w+)/))

Use ==~ to match the whole string.

Upvotes: 1

Related Questions