diff --git a/src/libs/qmljs/qmljsscanner.cpp b/src/libs/qmljs/qmljsscanner.cpp
index b7f82dd4205bcaf5a5fce91d55b5d151be8cd05c..58604df715d003fa9fa470cac24c1042719e1b10 100644
--- a/src/libs/qmljs/qmljsscanner.cpp
+++ b/src/libs/qmljs/qmljsscanner.cpp
@@ -123,6 +123,67 @@ static bool isNumberChar(QChar ch)
     }
 }
 
+static int findRegExpEnd(const QString &text, int start)
+{
+    if (start >= text.size() || text.at(start) != QLatin1Char('/'))
+        return start;
+
+    // find the second /
+    int index = start + 1;
+    for (; index < text.length(); ++index) {
+        const QChar ch = text.at(index);
+
+        if (ch == QLatin1Char('\\')) {
+            ++index;
+        } else if (ch == QLatin1Char('[')) {
+            // find closing ]
+            for (; index < text.length(); ++index) {
+                const QChar ch2 = text.at(index);
+                if (ch2 == QLatin1Char('\\')) {
+                    ++index;
+                } else if (ch2 == QLatin1Char(']'))
+                    break;
+            }
+            if (index >= text.size())
+                return text.size();
+        } else if (ch == QLatin1Char('/'))
+            break;
+    }
+    if (index >= text.size())
+        return text.size();
+    ++index;
+
+    // find end of reg exp flags
+    for (; index < text.size(); ++index) {
+        const QChar ch = text.at(index);
+        if (!isIdentifierChar(ch))
+            break;
+    }
+
+    return index;
+}
+
+
+static inline int multiLineState(int state)
+{
+    return state & 0b11;
+}
+
+static inline void setMultiLineState(int *state, int s)
+{
+    *state = s | (*state & ~0b11);
+}
+
+static inline bool regexpMayFollow(int state)
+{
+    return state & 0b100;
+}
+
+static inline void setRegexpMayFollow(int *state, bool on)
+{
+    *state = (on << 2) | (*state & 0b11);
+}
+
 QList<Token> Scanner::operator()(const QString &text, int startState)
 {
     _state = startState;
@@ -132,7 +193,7 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
 
     int index = 0;
 
-    if (_state == MultiLineComment) {
+    if (multiLineState(_state) == MultiLineComment) {
         int start = -1;
         while (index < text.length()) {
             const QChar ch = text.at(index);
@@ -145,7 +206,7 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
                 la = text.at(index + 1);
 
             if (ch == QLatin1Char('*') && la == QLatin1Char('/')) {
-                _state = Normal;
+                setMultiLineState(&_state, Normal);
                 index += 2;
                 break;
             } else {
@@ -155,7 +216,7 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
 
         if (_scanComments && start != -1)
             tokens.append(Token(start, index - start, Token::Comment));
-    } else if (_state == MultiLineStringDQuote || _state == MultiLineStringSQuote) {
+    } else if (multiLineState(_state) == MultiLineStringDQuote || multiLineState(_state) == MultiLineStringSQuote) {
         const QChar quote = (_state == MultiLineStringDQuote ? QLatin1Char('"') : QLatin1Char('\''));
         const int start = index;
         while (index < text.length()) {
@@ -170,10 +231,11 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
         }
         if (index < text.length()) {
             ++index;
-            _state = Normal;
+            setMultiLineState(&_state, Normal);
         }
         if (start < index)
             tokens.append(Token(start, index - start, Token::String));
+        setRegexpMayFollow(&_state, false);
     }
 
     while (index < text.length()) {
@@ -192,7 +254,7 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
             } else if (la == QLatin1Char('*')) {
                 const int start = index;
                 index += 2;
-                _state = MultiLineComment;
+                setMultiLineState(&_state, MultiLineComment);
                 while (index < text.length()) {
                     const QChar ch = text.at(index);
                     QChar la;
@@ -200,7 +262,7 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
                         la = text.at(index + 1);
 
                     if (ch == QLatin1Char('*') && la == QLatin1Char('/')) {
-                        _state = Normal;
+                        setMultiLineState(&_state, Normal);
                         index += 2;
                         break;
                     } else {
@@ -209,8 +271,14 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
                 }
                 if (_scanComments)
                     tokens.append(Token(start, index - start, Token::Comment));
+            } else if (regexpMayFollow(_state)) {
+                const int end = findRegExpEnd(text, index);
+                tokens.append(Token(index, end - index, Token::RegExp));
+                index = end;
+                setRegexpMayFollow(&_state, false);
             } else {
                 tokens.append(Token(index++, 1, Token::Delimiter));
+                setRegexpMayFollow(&_state, true);
             }
             break;
 
@@ -235,12 +303,13 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
                 // good one
             } else {
                 if (quote.unicode() == '"')
-                    _state = MultiLineStringDQuote;
+                    setMultiLineState(&_state, MultiLineStringDQuote);
                 else
-                    _state = MultiLineStringSQuote;
+                    setMultiLineState(&_state, MultiLineStringSQuote);
             }
 
             tokens.append(Token(start, index - start, Token::String));
+            setRegexpMayFollow(&_state, false);
         } break;
 
         case '.':
@@ -253,42 +322,52 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
                 break;
             }
             tokens.append(Token(index++, 1, Token::Dot));
+            setRegexpMayFollow(&_state, false);
             break;
 
          case '(':
             tokens.append(Token(index++, 1, Token::LeftParenthesis));
+            setRegexpMayFollow(&_state, true);
             break;
 
          case ')':
             tokens.append(Token(index++, 1, Token::RightParenthesis));
+            setRegexpMayFollow(&_state, false);
             break;
 
          case '[':
             tokens.append(Token(index++, 1, Token::LeftBracket));
+            setRegexpMayFollow(&_state, true);
             break;
 
          case ']':
             tokens.append(Token(index++, 1, Token::RightBracket));
+            setRegexpMayFollow(&_state, false);
             break;
 
          case '{':
             tokens.append(Token(index++, 1, Token::LeftBrace));
+            setRegexpMayFollow(&_state, true);
             break;
 
          case '}':
             tokens.append(Token(index++, 1, Token::RightBrace));
+            setRegexpMayFollow(&_state, false);
             break;
 
          case ';':
             tokens.append(Token(index++, 1, Token::Semicolon));
+            setRegexpMayFollow(&_state, true);
             break;
 
          case ':':
             tokens.append(Token(index++, 1, Token::Colon));
+            setRegexpMayFollow(&_state, true);
             break;
 
          case ',':
             tokens.append(Token(index++, 1, Token::Comma));
+            setRegexpMayFollow(&_state, true);
             break;
 
         case '+':
@@ -299,6 +378,7 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
             } else {
                 tokens.append(Token(index++, 1, Token::Delimiter));
             }
+            setRegexpMayFollow(&_state, true);
             break;
 
         default:
@@ -312,6 +392,7 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
                     ++index;
                 } while (index < text.length() && isNumberChar(text.at(index)));
                 tokens.append(Token(start, index - start, Token::Number));
+                setRegexpMayFollow(&_state, false);
             } else if (ch.isLetter() || ch == QLatin1Char('_') || ch == QLatin1Char('$')) {
                 const int start = index;
                 do {
@@ -322,8 +403,10 @@ QList<Token> Scanner::operator()(const QString &text, int startState)
                     tokens.append(Token(start, index - start, Token::Keyword)); // ### fixme
                 else
                     tokens.append(Token(start, index - start, Token::Identifier));
+                setRegexpMayFollow(&_state, false);
             } else {
                 tokens.append(Token(index++, 1, Token::Delimiter));
+                setRegexpMayFollow(&_state, true);
             }
         } // end of switch
     }
diff --git a/src/libs/qmljs/qmljsscanner.h b/src/libs/qmljs/qmljsscanner.h
index 9c9b43bd18063e40cb6c3c0f21b326a454c75343..777fd1ba0522c063185d68f36e53257284049086 100644
--- a/src/libs/qmljs/qmljsscanner.h
+++ b/src/libs/qmljs/qmljsscanner.h
@@ -59,7 +59,8 @@ public:
         Colon,
         Comma,
         Dot,
-        Delimiter
+        Delimiter,
+        RegExp
     };
 
     inline Token(): offset(0), length(0), kind(EndOfFile) {}
@@ -82,7 +83,8 @@ public:
         Normal = 0,
         MultiLineComment = 1,
         MultiLineStringDQuote = 2,
-        MultiLineStringSQuote = 3
+        MultiLineStringSQuote = 3,
+        RegexpMayFollow = 4 // flag that may be combined with the above
     };
 
     Scanner();
diff --git a/src/plugins/qmljseditor/qmljscompletionassist.cpp b/src/plugins/qmljseditor/qmljscompletionassist.cpp
index 6de4e825493a6b44766544aa7c72f30c8633f0a4..3bda6afd8463bfe36c53c2e8078f7471f71dd4bd 100644
--- a/src/plugins/qmljseditor/qmljscompletionassist.cpp
+++ b/src/plugins/qmljseditor/qmljscompletionassist.cpp
@@ -681,7 +681,7 @@ bool QmlJSCompletionAssistProcessor::acceptsIdleEditor() const
             if (column >= tk.begin() && column <= tk.end()) {
                 if (charBeforeCursor == QLatin1Char('/') && tk.is(Token::String))
                     return true; // path completion inside string literals
-                if (tk.is(Token::Comment) || tk.is(Token::String))
+                if (tk.is(Token::Comment) || tk.is(Token::String) || tk.is(Token::RegExp))
                     return false;
                 break;
             }
diff --git a/src/plugins/qmljseditor/qmljshighlighter.cpp b/src/plugins/qmljseditor/qmljshighlighter.cpp
index ac3f408aa46398630942d53f0d8f3082cdd84c9d..55b917db357f092ece0975155ff16815ff1bd6e2 100644
--- a/src/plugins/qmljseditor/qmljshighlighter.cpp
+++ b/src/plugins/qmljseditor/qmljshighlighter.cpp
@@ -116,6 +116,10 @@ void Highlighter::highlightBlock(const QString &text)
                 setFormat(token.offset, token.length, m_formats[CommentFormat]);
                 break;
 
+            case Token::RegExp:
+                setFormat(token.offset, token.length, m_formats[StringFormat]);
+                break;
+
             case Token::LeftParenthesis:
                 onOpeningParenthesis('(', token.offset, index == 0);
                 break;
@@ -229,7 +233,8 @@ void Highlighter::highlightBlock(const QString &text)
 
         switch (token.kind) {
         case Token::Comment:
-        case Token::String: {
+        case Token::String:
+        case Token::RegExp: {
             int i = token.begin(), e = token.end();
             while (i < e) {
                 const QChar ch = text.at(i);