3

複数のソースからのツイートを演習として照合するウィジェットをコーディングしようとしています(ここに似たようなものがありますが、a)そこで提供されるリストオプションは私のリストをロードしませんでした、b)それは便利な学習演習です!)。その一環として、Twitterハンドル(「@」の後に文字が続く)をユーザーのTwitterページへのリンクに置き換える正規表現を作成したいと思いました。ただし、たとえば、ツイート内の電子メールアドレスの誤検知は望ましくありませんでした。

したがって、たとえば、交換は送信する必要があります

Hey there @twitteruser, my email address is address@gmail.com

Hey there <a href="http://twitter.com/twitteruser">@twitteruser</a>, my email address is address@gmail.com

この質問に導かれて、Javascriptでネガティブな後読みを複製する何らかの方法が必要であることを示唆し、次のコードを作成しました。

tweetText = tweetText.replace(/(\S)?@([^\s,.;:]*)/ig, function($0, $1){
    return $1 ? $0 + '@' + $1 : '<a href="http://www.twitter.com/' + $0 + '">@' + $0 + '</a>'
});

ただし、三項演算子の最後の部分がトリガーされる場合、$0には「@」記号が含まれます。これは私にとっては予想外でした-「@」は括弧で囲まれていなかったので、$ 0は「([^ \ s、。;:] *)」と一致すると予想しました-つまり、Twitterユーザーのユーザー名(後、なし、「@」)。$ 0.substring(1)を使用することで目的の機能を取得できますが、理解を深めたいと思います。

誰かが私が誤解していることを指摘してもらえますか?私は正規表現にまったく慣れておらず、Javascriptで記述したことも、ネガティブな後読みを使用したこともありません。

4

4 に答える 4

3

いずれにせよ、 の前にオプションの非スペースを一致させよう@とし、一致が見つかった場合に一致を拒否する代わりに、 ? の前にスペース (または文字列の先頭) を必要としないのはなぜ@ですか?

tweetText = tweetText.replace(
    /(^|\s)@([^\s,.;:]*)/g,
    '$1<a href="http://www.twitter.com/$2">@$2</a>'
);

これは単純であるだけでなく、かなり高速になる可能性もあります。これは、regexp が考慮する必要がある潜在的な一致がはるかに少ないためです。

于 2012-07-01T00:02:45.063 に答える
2

ほとんどの REGEX 実装の標準的な動作と同様に、マッチ ゼロはマッチ全体 (その一部としてサブマッチを含む - 非キャプチャとしてマークされているものも含む) であり、その後のマッチはキャプチャされたサブマッチです。www.regular-expressions.info をチェックしてください。例えば:

console.log('hello, there'.match(/\w+(?:,) ?(\w+)/));

配列を提供します

["hello, there", "there"] //the first sub-match is non-capturing

JavaScript は後読みをサポートしていませんが、これにはシミュレーションがあり、私が書いたような完璧なものはありません。一般に、JavaScript の REGEXP 実装は、他のいくつかの言語よりも脆弱です。省略の例としては、次のようなものがあります。

  • 後読み
  • 名前付き原子団
  • ほとんどの修飾子 (ただし、重要なものはそこにあります - グローバル、大文字と小文字を区別しない、複数行)
  • 重要なのは、グローバルにマッチングしながらサブグループをキャプチャする機能
于 2012-06-30T23:50:46.770 に答える
2

物事を複雑にしすぎているのではないかと思います。これを試してユーザー名を取得し、独自のヘルパー関数を作成してマークアップを作成してください。

var getTwitter = function (str) {
  var re = /[^\w](@\w+)/g,
      matches = [],
      tweets = []
  while (matches = re.exec(str))
    tweets.push(matches[1])
  return tweets
}

デモ: http://jsfiddle.net/elclanrs/gLvX4/

于 2012-06-30T23:52:44.020 に答える
0

あなたは複雑すぎますが、それほど複雑ではありません。1行のコードですべてを一度に行うことができます。これを行うだけです\W@(\w+)

ライブデモhttp://jsfiddle.net/Victornpb/Wugvd/

//make twitter username links
function linkTwitterNames(elm){
    elm.innerHTML = elm.innerHTML.replace(/\W@(\w+)/g, ' <a class="twitter" href="http://twitter.com/$1" target="_blank">@$1</a>');
}
于 2013-01-20T03:06:01.897 に答える