2

I'm handling tweets like @Alice @ home. I want to convert user mentions to normal words (e.g. @Alice => Alice) but keep the individual @ as a surrogate for at. So simply replacing all occurrences of @ won't work.

I found out about the concept of word boundaries, but I haven't been able to make them work for this. For one,

print re.sub(r'\b@\b', '', '@Alice @ home')

doesn't change anything, while

print re.sub(r'\bAlice\b', '', '@Alice @ home')

results in @ @ home. So I assume that the at-sign (@) does not count as part of a word.

In short, I'm basically looking for the pattern so that

print re.sub(pattern, '', '@Alice @ home')

outputs Alice @ home.

Thanks for any hints.

4 Answers 4

4

You may play with the boundaries \B and \b

>>> print re.sub(r'\B@\b', r'', '@Alice @ home')
Alice @ home
>>> print re.sub(r'\B@\b', r'', 'foo @Alice @ home')
foo Alice @ home

\B matches between two word characters or between two non-word characters. So \B@ in the above regex matches the @ before Alice and the another separate @ symbol. \b matches between a word character and a non-word character (vice versa). So the following \b makes the pattern to match only the first because the first @ itself followed by a word character ie, A.

Sign up to request clarification or add additional context in comments.

1 Comment

Great answer. I upvoted it per the About-face in my answer. Thanks!
3
(?:^|(?<=\s))@(?!\s)

Try this.This will replace @ only from the start of word.if @ is in the middle of word like as@sas it will save it.See demo.

https://regex101.com/r/tX2bH4/44

re.sub(r'(?:^|(?<=\s))@(?!\s)','',s)

Comments

2

Initial Answer

Try the following regex:

@(?! )

Here are a couple examples of how it performs:

>>> print re.sub(r'@(?! )', '', '@Alice @ home')
Alice @ home
>>> print re.sub(r'@(?! )', '', 'Whatever @Alice @ home')
Whatever Alice @ home

You can also test it with a related regex fiddle.

Key points:

  • @the at-sign
  • (?! ) – a negative lookahead that matches anything but a space (i.e. not followed by a space)

Personally I find the zero-width word-boundary assertions (\b and \B) a bit distracting and prefer to use zero-width lookarounds for this sort of thing, but TMTOWTDI.

About-face

I thought about this more (as usual), and what I found is admittedly a compelling case for the zero-width word-boundary assertions' simplicity and start- and end-of-string matching.

Consider a fuller set of conceivable tweets:

@Alice @ home
Whatever @Alice @ home
What're you lookin' @
What're you lookin' @?

It turns out that to get these right requires a much more complicated negative lookahead, turning my initial regex into:

@(?![ \W]|$)

As before, here are examples of how it performs:

>>> print re.sub(r'@(?![ \W]|$)', '', '@Alice @ home')
Alice @ home
>>> print re.sub(r'@(?![ \W]|$)', '', 'Whatever @Alice @ home')
Whatever Alice @ home
>>> print re.sub(r'@(?![ \W]|$)', '', "What're you lookin' @")
What're you lookin' @
>>> print re.sub(r'@(?![ \W]|$)', '', "What're you lookin' @?")
What're you lookin' @?

And as before, you can also test it with a related regex fiddle.

But a word-boundary pattern like Avinash Raj employed gets this fuller set of conceivable tweets right...with much less fanfare:

>>> print re.sub(r'\B@\b', '', '@Alice @ home')
Alice @ home
>>> print re.sub(r'\B@\b', '', 'Whatever @Alice @ home')
Whatever Alice @ home
>>> print re.sub(r'\B@\b', '', "What're you lookin' @")
What're you lookin' @
>>> print re.sub(r'\B@\b', '', "What're you lookin' @?")
What're you lookin' @?

Test it out with another related regex fiddle if you like too.

Bottom line, this has been a cool learning experience for me to question what I tend to prefer using, and I hope you find it the same: onward on our word-boundary-assertion adventures! :)

Comments

1

The simplest way working for me:

>>> s = '@Alice @ home'
>>> re.sub('\s@\s', ' at ', s).replace('@', '')
'Alice at home'

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.