質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

2回答

3563閲覧

c#のソースからコメントを除去したいです。

yukke7624

総合スコア11

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2020/02/25 06:11

編集2020/02/25 09:01

前提・実現したいこと

C#のソース文字列をstringとして受け取って、何らかの方法を使ってコメントを除去したstringを返す関数を作ろうとしています。
現在は正規表現を使って実現出来ないかと検証をしているのですが、コメントの一部パターンが上手くいかないので助言頂きたく投稿しました。

@"(/*(?>[^*]|(*+[^*/]))**+/)|(//.*)"

上記の正規表現までは出来たのですが、これだと下記の要件の一部が満たせませんでした。

・行頭にある「//」での一行コメントの除去→OK
・行の途中にある「//」での一行コメントの除去→OK
・行頭から始まる「/* ~ /」での1行コメントの除去→OK
・行の途中にある「/
~ /」での1行コメントの除去→OK
・行頭から始まる「/
~ /」での複数行コメントの除去→OK
・行の途中にある「/
~ */」での複数行コメントの除去→OK
・ダブルクォーテーションの中に含まれる「//」は文字列なので除去対象外とする→NG

正規表現やRoslyn、もしくはその他方法を使って上記要件を満たせる方法をご教授頂きたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/02/25 06:18

正規表現では中途半端なものしかできません。$"" や @"" の扱いやエスケープの扱いなどで困るでしょう。Roslyn を使いましょう。
yukke7624

2020/02/25 06:41

Roslynでコメント除去したものをstringとして出力する方法が分からず、挫折して正規表現でのコメント除去の方法を模索している。 という経緯です...。
Zuishin

2020/02/25 06:51 編集

正規表現一本ではかえって難しくなります。用意された解析器を使わないのであれば、@"" は複数行に対応していてエスケープの種類が違うこと、$"" は文字列扱いされない部分があること、$@"" や @$"" もあることなどに気をつけて、モードを変えながら頭から解析していくのが良いと思います。
Zuishin

2020/02/25 06:53

Roslyn を使ってもいいのであれば、その旨追記しておけば、その方向での回答が付くかもしれません。
yukke7624

2020/02/25 08:58

ご丁寧にありがとうございます。 多方面から情報を収集しながら実装方法を模索します。
shiketa

2020/02/25 14:03

cppコマンド (C言語のプリプロセッサ)を使ってみては? Javaソースのコメント抜きの実質の行数を勘定するためにcppを使っていたりします。 `$ cpp xx.cs | sed -e '/^ *$/d' -e '/^#/d' | wc -l` とかやって。
guest

回答2

0

ベストアンサー

How can I remove all comments from a file of code
FAQ(32)

雑でよければ上記リンクの通りで削除はできました(ただし空行が残りますorz

cs

1using System; 2using Microsoft.CodeAnalysis; 3using Microsoft.CodeAnalysis.CSharp; 4 5namespace Questions243387 6{ 7 internal class Program 8 { 9 private static void Main() 10 { 11 var tree = SyntaxFactory.ParseSyntaxTree( 12 @"using System; 13// 行頭にある一行コメント 14/* 行頭から始まる1行コメント */ 15/* 16 * 行頭から始まる複数行コメント 17 */ 18namespace ConsoleApp1 19{ 20 class Program // 行の途中にある一行コメント 21 { 22 static void Main(string[] /* 行の途中にある1行コメント */ args) 23 { 24 Console.WriteLine(""ダブルクォーテーションの中に含まれる「//」""); 25 } 26 } 27}"); 28 29 var rewriter = new CommentRemover(); 30 var newRoot = rewriter.Visit(tree.GetRoot()); 31 Console.WriteLine(newRoot.ToFullString()); 32 } 33 34 private class CommentRemover : CSharpSyntaxRewriter 35 { 36 public override SyntaxTrivia VisitTrivia(SyntaxTrivia trivia) 37 { 38 if(trivia.Kind() == SyntaxKind.SingleLineCommentTrivia 39 || trivia.Kind() == SyntaxKind.MultiLineCommentTrivia) 40 { 41 return default; 42 } 43 return base.VisitTrivia(trivia); 44 } 45 } 46 } 47}

出力

cs

1using System; 2 3 4 5namespace ConsoleApp1 6{ 7 class Program 8 { 9 static void Main(string[] args) 10 { 11 Console.WriteLine("ダブルクォーテーションの中に含まれる「//」"); 12 } 13 } 14}

こちらのコードでは行ごと削除できてるっぽいのですが、何をしてるのかわかりません^^;
CommentStripper/CommentStripperCSharpSyntaxRewriter.cs at master · MichaelKetting/CommentStripper

投稿2020/02/25 12:11

編集2024/08/31 17:16
TN8001

総合スコア10022

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

  1. ダブルクオーテーションの中の//を正規表現を使い別の文字(その文字を仮にAとする)に置き換える
  2. 上の正規表現を実行する
  3. 置き換えたAを//に戻す

のように、3段階にしてはどうでしょうか?

投稿2020/02/25 12:05

編集2020/02/26 00:01
fdaskjlfda

総合スコア40

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問