正規表現について質問です。

テキストファイル内の文字列に対して、URL以外の「&」を「&」に置換したいのですが、
普通に置換してしまうと、URL内の「&」も全角になってしまうため、
正規表現で回避しようと考えています。

この場合、正規表現はどのように記述すればよいか、教えていただけると大変助かります。

----------------------------------------------------------------------
(成功例)
ガチャピン&ムック
http://hogehoge.jp/index.html?k=2011&id=0414

↓↓↓↓↓↓

ガチャピン&ムック
http://hogehoge.jp/index.html?k=2011&id=0414

----------------------------------------------------------------------


また、正規表現を使わなくてもできるなど、別の提案もOKです。
質問に不備があれば、その旨ご指摘お願いいたします。

正規表現勉強中のため、何卒よろしくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

<回答>


自分も、これを正規表現とエディタの通常置換だけで綺麗に解決する方法は思い浮かびませんでした。
エディタのマクロを使うか、スクリプト言語が使えればそれほど難しい話では無いと思います。

例えばですが、先読み否定を利用してこんな正規表現を作ってみます。
※想定処理系は鬼車で、実験環境は「サクラエディタ+bregonig.dll(v 2.00)」です。

^(?![  ⇒]?\w+?p://)(.*)&

こうするとキャプション1に&までの文字列が入るため、置換後ワードに

$1置換希望文字列

とでも書けば、一見動いたように見えます。

しかしこれだと、1行内に&が複数現れるケースで、最後の1つしか置換出来ない事になります。
.*を.*?としても、最初の1つになるだけでしょう
自分の知識量だとこの辺を解決できる記法が無いとまでは断言できませんので、出来る!というのがあれば是非知りたいなと思います。


※参考変換例は、行頭に#を付与しています。
## 元データ
#ガチャピン&ムック
#ガチャ&ピン&ムック
#http://hogehoge.jp/index.html?k=2011&id=0414
# http://hogehoge.jp/index.html?k=2011&id=0414
# http://hogehoge.jp/index.html?k=2011&id=0414
#⇒http://hogehoge.jp/index.html?k=2011&id=0414

## 置換後
#ガチャピン&ムック
#ガチャ&ピン&ムック
#http://hogehoge.jp/index.html?k=2011&id=0414
# http://hogehoge.jp/index.html?k=2011&id=0414
# http://hogehoge.jp/index.html?k=2011&id=0414
#⇒http://hogehoge.jp/index.html?k=2011&id=0414


<おまけ>
ただ、スクリプト言語を利用してもよいのであれば、いろんなアプローチで簡単に解決できます。
一番真面目な方法はURLが含まれることを専用ライブラリで解析する方法でしょうが、そこまでやらずにこの正規表現のようにURIっぽいものを弾いてみます。

https://ideone.com/N1Ubf

手法選択の中で一案として貰えればと思います。
Perlが代表格ですが、正規表現はスクリプト言語内で真価を発揮しますので。
    • good
    • 0
この回答へのお礼

回答いただきありがとうございます。
正規表現はスクリプト言語内が得意分野なのですね。お恥ずかしながら特性を理解していませんでした。
置換ルールが固定されているので無理にエディタだけでやろうとせず、専門家に依頼することにします。
とても助かりました。ありがとうございました。

お礼日時:2011/05/06 10:43

正直、あらゆるケースに対応したものを全自動でやろうとすると難しいと思います。



まず、その置換を行うソフトは何か?
テキストエディタの置換機能なのか、sedなのか、perlなのか、PHPなのか。
ソフトが違えば、正規表現自体に違いがあります。
半角→全角変換なら、「全角」が正しく使える(マルチバイト文字を「1文字」として扱える/マルチバイトの途中のバイトからはマッチしない)処理系が求められます。

次に入力がどんな形式になっているのか?その入力形式の特徴を使えば楽にできるかもしれません。
例えば、URLが 「必ず単独1行に改行無しでURLだけが書かれている」状態なら、そのような行を処理しない、という方法が使えます。が、他の内容と同じ行にあったり、途中で改行で切れることもあったり、だと面倒です。
例えば、URLは「半角英数記号」が基本であり、置換したい&の前後は必ず「全角」であるならば、後方参照を使って「前の全角&後の全角」→「前の全角&後の全角」のように置換できます。が、URLに全角を使っていたり、置換する&の前後が全角とは限らない、となると面倒です。

次に作業量がどれくらいなのか?
数ファイルだけなら、エディタの確認付き置換を使って、人間が判断するのが確実です。

この回答への補足

早速のご回答ありがとうございます。
以下、補足いたします。

⇒まず、その置換を行うソフトは何か?
└テキストエディタ、もしくは置換用のフリーソフト(Repl-Ace)を考えています。

⇒入力がどんな形式になっているのか?
└基本的には単独1行で書かれているのですが、たまにURLの前に全角スペースか半角スペース、もしくは「⇒」が入ります。

⇒作業量がどれくらいなのか?
└一度に作業するのは数ファイルなのですが、結構漏れがでたりしてしまうため、あらかじめ正規表現での置換を登録しておこうと考えています。
置換するところは他にもありますので、まとめてやりたいです。

度々すみませんが、何卒知恵を貸してくださいませ。

補足日時:2011/04/15 10:04
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

お礼日時:2011/05/06 10:43

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q正規表現でのパイプ(or)を減らしたいのですが

いつもお世話になっています。
正規表現のパイプ(|)は非常に遅くなるらしいので、[]内に並べるようにプログラムを修正しようと思っています。それで、
/a|b|c/ ---> [abc]
のような方法は、よく紹介されているのですが、a,b,cが単独文字ではなく、単語になっているような場合、
/abc|def|ghi/ ---> [(abc)(def)(ghi)]
だと多分ダメですよね(今実行環境が無く確認できません)。
それで、各々の単語を
$a = 'abc';
$d = 'def';
$g = 'ghi';
のようにあらかじめ定義しておいて、
/$a|$d|$g/ ---> [$a$d$g]
というように書き換えると、うまくいくのでしょうか?
やり方が間違っていましたら、ご指摘いただきたく、よろしくお願いします。

Aベストアンサー

ブラケットの中は独立したキャラクタとして扱われるので文字列をそこに収めることはできません。
#これは#1の方の回答にもあるとおり

そんなに気になるのなら
Regexp::Optimizer - optimizes regular expressions - search.cpan.org
http://search.cpan.org/~dankogai/Regexp-Optimizer-0.15/lib/Regexp/Optimizer.pm
このモジュールを使ってみるとか。

正規表現のマッチングを遅くする原因は色々あるので、
本当にその辺を知りたければ

oreilly.co.jp -- Online Catalog: 詳説 正規表現 第2版
http://www.oreilly.co.jp/books/4873111307/

を頑張って読破しましょう。

Qテキストエディタの正規表現による置換について

例えば、テキスト内に以下の文章があった場合(広がると伝播の間にタブがはいっています)
広がる     伝播, 蔓延, 流布, 拡散, 伝播する, 延展する, 蔓延する, 流布する, 広げる

この「広がる     伝播」のみを残して、右のカンマで区切られた余計なもの(蔓延, 流布, 拡散, 伝播する, 延展する, 蔓延する, 流布する, 広げる)を一括で削除したいのです。

改行されて、同様の文章が続きますので、全行で一括置換したいのです。

可能でしょうか?

Aベストアンサー

No.2の回答者です。

前回の回答は、ちょっと勘違いした部分がありました。
タブ区切りも入ったテキストの最初のカンマ以降を削除でしたね。

[置換前] ([^\t]+\t)([^,]*),{1}.*
[置換後] $1$2

これで置換できませんか?

¥1になってしまうのは全角の¥のためですね。
半角の¥1や$1なら大丈夫なはずです。
[置換後]は半角で$1$2としてください。
サクラエディタの場合は半角の$が既定なのですが、私はWordを
よく使っているので、癖で半角の¥にしていることが多いので。
どちらも認識するので、つい¥1と書いてしまいました。
訂正してお詫びします。

Q【Ruby or Perl・正規表現】ある文字列の先頭5文字を残して削除するには?

初心者質問で恐縮です。
RubyもしくはPerlで、ある文字列の先頭5文字を除く文字をすべて削除する(先頭5文字のみの文字列にする)には、どのような記述をすればよいでしょうか。
教えていただけるとうれしいです。
よろしくお願いします。

Aベストアンサー

Perlなら

s/^(.....).*$/$1/;

でいけるように思います。

Q正規表現で置換

正規表現の初心者です。

テキストエディタを使って、「@:」で始まる以外の行の先頭に「//」を挿入してコメントアウトしたいのですが、正規表現がうまく書けません。

検索対象:
^[^(@:)]
置換文字列:
//

でいいのかなと思ったのですが、[]の中ではグルーピング用の()も文字として認識されてしまうのですね。

どのように書いたら正しく置換されるでしょうか。
どうかご教示ください。

Aベストアンサー

一回でやろうと考えない方が無難な気がします。一番確実なのは、まず全ての行頭に//を追加して、次に//@:を@:に置換することじゃないでしょうか?

というのは、うまくマッチさせる正規表現を書けたとしても、「行頭+パターン」の形になるため、パターンにあたる行頭の1文字が//に置換されてしまう結果になるんじゃないかと心配なので。

なお、エディタの種類によっては、行頭に置換をかけると永遠に置換し続けてしまう物もありうるので、注意してください。

Q言語ではなく、正規表現のみで複数の条件を記述する方法 ?

一つの条件の正規表現は書けるようになりましたが、
条件が重なった場合の対処の仕方がわかりません。

my $val = "12";
#数字のみ
if($val =~ /^[0-9]+$/){
# match!
}

#0で無い
if($val !~ /^0$/){
# match!
}

# 数字で0でない <---複数条件



# 言語でカバーするのではなく、正規表現のみ(1つの正規表現)
# でANDやORやXORができるパターンの記述方法が知りたいです。
if($val =~ /^[0-9]+$/) && ($val !~ /^0$/){
# match!
}

Aベストアンサー

条件式の AND や XOR に相当するものは、正規表現には存在しません。というのも、正規表現で表すのは「パターン」であり、「条件」ではないからです。
※OR についてはパターンの選択を行う | が相当します。

このため、複数の条件式にしたくない場合は、1つで複数の条件を満たすパターンを書くしかありません。また、汎用的な方法もないので、ケースごとにパターンを書き下ろさなければなりません。

No.2 補足より
> 言語を使った&& ||ではスマートではなく、複雑な内容になってきた場合、1行で解決できた方が発展性があるかと思いましてこだわっております。

確かに「0ではない数字」程度のことを複合条件にするのはスマートとは言えないでしょう。しかし、関連性のない事柄を無理なパターンで表現するくらいなら、分解して && や || で結合した方がすっきりします。
また、大概の場合、1行で無理に解決した方が発展性には欠けますので、発展性やメンテナンス性を求めるならば、あまりこだわらない方がよいでしょう。

Q正規表現の置換で数値のみを抽出するには

お世話になっております。
秀丸エディタの置換で、数値部分のみを抽出したいと考えています。

(例)
http://www.abd.com/cat/
http://www.abd.com/cat/54678/
http://www.abd.com/cat/eco/
http://www.abd.com/cat/eco/as/458/index.php
http://www.abd.com/cat2/
http://www.abd.com/cat/5412578/
http://www.abd.com/cat/bs/5894/
http://www.abd.com/cat3/
・・・

正規表現を使ってこのように数値のみを抽出したいです。

54678
458
5412578
5894
・・・

検索してみましたがヒントになりそうなのはありませんでした。
ご教授いただければ幸いです。よろしくお願いいたします。

Aベストアンサー

検索文字列:[^0-9\n]|^\n
置換文字列:なし

なら、空行削除も含めて一発でできます。

Q正規表現について

HTMLファイルを読み込み、特定の文字列にリンクを付けて出力したいのですが上手くいきません。

例: <img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。

 ↓正規表現をキーワードにしてリンクを付けたい。

正:<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に<a href="seiki_hyougen.html">正規表現</a>を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。

誤:<img src="./seiki_hyougen.gif" alt="<a href="seiki_hyougen.html">正規表現</a>についての説明">更に<a href="seiki_hyougen.html">正規表現</a>を知りたい方は、<a href="special.html"><a href="seiki_hyougen.html">正規表現</a>の詳しい説明</a>をクリックして下さい。


尚、下記URLのサンプルを参考にしてスクリプトを作成しています。
http://php.oss.eznetsols.org/manual/ja/function.preg-split.php

$r = preg_split('((\/a>)|(<a))', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
for ($i = 0; $i < count($r); $i++) {
if ($r[$i] == "<a") {
$i++; continue;
}
$r[$i] = preg_replace(
"/(正規表現)/i", "<a href='seiki_hyougen.html'>\\1</a>", $r[$i]
);
}
return join("", $r);

この(正規表現)の部分で上手い正規表現を使えばalt="×××"の中にリンクタグが入らないようにできるのでは?と思っているのですが・・・。

どうか、良い方法を教えて下さい。よろしくお願いいたします。

HTMLファイルを読み込み、特定の文字列にリンクを付けて出力したいのですが上手くいきません。

例: <img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。

 ↓正規表現をキーワードにしてリンクを付けたい。

正:<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に<a href="seiki_hyougen.html">正規表現</a>を知りたい方は、<a href="special.html">正規表現の詳しい説明...続きを読む

Aベストアンサー

ごめんなさい。複数のキーワードに対応しようとして
余計なことをしてしまいました。
訂正します。

<?php
$msg = <<<EOF
<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。
EOF;

$links = array (
'正規表現' => '<a href="seiki_hyougen.html">正規表現</a>',
);

$link_keys = array_keys($links);
$link_values = array_values($links);

# 表示用関数
function printandreturn ($str) {
print stripslashes("$str");
return "";
}

function printwithlink ($str) {
global $link_keys, $link_values;
print str_replace($link_keys, $link_values, stripslashes($str));
return "";
}

# 処理開始

# 文字化け対策
$msg = str_replace("\\", "\\\\", $msg);

# メインループ
while (strlen($msg)) {
# アンカー部分をスキップ
if (strpos($msg, '<a') === 0) {
$msg = preg_replace("|^(.*?</a>)|e", "printandreturn ('$1')", $msg);
continue;
}
# タグ部分をスキップ
if ($msg[0] == '<') {
$msg = preg_replace("|^(<.*?>)|e", "printandreturn ('$1')", $msg);
continue;
}

# 次のタグまでをリンク付きで表示
foreach ($links as $key => $value) {
$msg = preg_replace("|^([^<]+)|e", "printwithlink ('$1')", $msg);
}
}
?>

ごめんなさい。複数のキーワードに対応しようとして
余計なことをしてしまいました。
訂正します。

<?php
$msg = <<<EOF
<img src="./seiki_hyougen.gif" alt="正規表現についての説明">更に正規表現を知りたい方は、<a href="special.html">正規表現の詳しい説明</a>をクリックして下さい。
EOF;

$links = array (
'正規表現' => '<a href="seiki_hyougen.html">正規表現</a>',
);

$link_keys = array_keys($links);
$link_values = array_values($links);

# 表示用関数
function printandr...続きを読む

Q秀丸の正規表現を使った置換について

秀丸エディターを使ってテキストの編集をしているのですが、正規表現を使って下記の様なテキストを削除したいのですが、方法はあるでしょうか?




様々なテキスト ~ 約100字程度





上記のように改行3個と改行4個に挟まれたテキストを全て削除したいので \n\n.*\n\n\n としてもダメなようで
記述方法をご教授下さい

Aベストアンサー

ほげほげ↲



様々なテキスト ~ 約100字程度↲




ふがふが↲

ってテキストのケツに改行がはいるので改行5つじゃない?
秀丸はよくわからないけど
「\n{3}.+?\n{4}」的な感じの処理だと思うけど・・・

Q正規表現について

今lexのプログラムを書いているのですが、正規表現の部分でつまずいてしまいました。perlの正規表現なら分かるのですが、lexと少しかってが違い困っています。lexの正規表現でコメント(プログラム中で/**/で囲まれた部分)を読み飛ばす時には、どのような正規表現にしたら是非教えてください。なお/**/の中には文字列*/は出てこないと過程していいとのことでした。
解答お願い致します。

Aベストアンサー

>できるだけ正規表現で表したいのですが・・・面倒ですよね(笑)
それはなぜですか?
もし自分自身の興味としてそうしたいのであれば、解答をそのまま教えて欲しいということはないですよね。

>なお/**/の中には文字列*/は出てこないと過程していいとのことでした。

何かの課題で出されていている問題で、その解答が欲しい?

んじゃあ考え方のヒントだけ。

xy を含まないものにマッチする正規表現
http://www.din.or.jp/~ohzaki/regex.htm#WithoutXY

の応用です(というかそのまま)。
/\* ('*/' を含まない文字列) \*/
という正規表現を、上のURLの先で説明されているパターンを適用してやればできるでしょう。

Q正規表現?の置換方法について!(以降削除等)

置換方法についてお詳しい方よろしくお願いいたします。

現在行いたいことは、ある対象とする記述以前、または以降の内容を削除したいと考えております。

具体的には、仮に<div id="hogehoge">とあったとします。

この場合、これ以前の記述を全て削除の置換を行いたいと思っています。
どんな記述があっても、<div id="hogehoge">の記述以前は全削除という置換です。

また、これは以前なのですが、この記述が終わったマーク、こちらも例えばですが<!--//hogehohe-->という記述終了を指定するコメントがあったとします。

その場合、<!--//hogehohe-->以降の記述は全て削除という指定を行いたいと思います。

伝わりますでしょうか。。。

何かを対象にする置換は調べたところ見つかったのですが、対象をもとに以前、以後という指定での置換が分かりません。><

お詳しい方いらっしゃいましたらアドバイスを頂けないでしょうか。

宜しくお願いいたします。

Aベストアンサー

notepad++ で確認
http://notepad-plus-plus.org/

CTRL+H または メニュー/検索/置換 から「置換」のダイアログを開き

検索文字列: ^.+(<div id="hogehoge">)
置換文字列: $1
検索モード: 正規表現
. matches newline: チェックを入れる (ファイル先頭まで削除する場合)
. matches newline: チェックしない (同じ行の頭まで削除する場合)
置換ボタンを押す
にて「以前の記述を全て削除」ができます

検索文字列: (<!--//hogehoge-->).+$
なら「以降の記述は全て削除」です


人気Q&Aランキング