HTML文字列に実際にテキストが含まれているか、HTMLタグとエンティティのみで構成されているかをC#で確認することは可能ですか?
例えば
string str = @"<p xmlns=""http://www.w3.org/1999/xhtml"" />"
これには HTML タグのみが含まれ、テキストは含まれません。
HTML文字列に実際にテキストが含まれているか、HTMLタグとエンティティのみで構成されているかをC#で確認することは可能ですか?
例えば
string str = @"<p xmlns=""http://www.w3.org/1999/xhtml"" />"
これには HTML タグのみが含まれ、テキストは含まれません。
XDocument doc = XDocument.Parse(yourString);
bool containsText = doc.Root.DescendantNodes()
.Count(el => el.GetType() == typeof (XText)) > 0
ヒント:
XDocument.Parse(...) の有効な xml を確保するために、このアプローチをSGMLReaderと組み合わせることがよくあります。
これは、HTML で正規表現を使用することが有効なアプローチである 1 つのケースです。HTML は通常の言語ではないため、通常は HTML にはありません。ただし、私たちが気にかけている機能は通常の言語で表現できます。HTML を通常の言語ではないものにしているタグの潜在的に無限のネストについては気にしません。
つまり、正規表現で HTML を解析できないという規則は引き続き適用されますが、実際にはここで解析していません。(ちなみに、少なくとも理論上は、再帰的な正規表現でも HTML を解析できます)。
それを書く際のトリッキーなビットは、それ>
が属性値で許可されていることです。そうでない場合は、単純な式^(<[^>]*>)$
だけでタグのみの文字列に一致させることができます (必要に応じて、空白も許可するように調整してください)。
ただし、属性を扱うのは面倒な>
ので、私は好きです:
public static bool IsTagsOnly(string html)
{
bool inTag = false;
char attChar = '\0';
foreach(char c in html)
{
if(char.IsWhiteSpace(c))//include or excise this bit depending on whether you count whitespace as "content"
{
continue;
}
if(!inTag)
{
if(c == '<')
inTag = true;
else
return false;
}
switch(c)
{
case '\'':
switch(attChar)
{
case '\'':
attChar = '\0';
break;
case '\0':
attChar = '\'';
break;
}
break;
case '"':
switch(attChar)
{
case '"':
attChar = '\0';
break;
case '\0':
attChar = '"';
break;
}
break;
case '>':
if(attChar == '\0')
inTag = false;
break;
}
}
return true;
}
入力をHTML Agility Packで解析すると、プロパティをチェックしてdocument.DocumentNode.InnerText
、フラグメント全体にテキストがあるかどうかを確認できます。
HTML を扱うときはいつでも、かなりトリッキーです。
正規表現で簡単に実現できますが、HTML を正規表現で解析することは悪い考えであることに注意してください!!! . これは単純に、HTML が正しくフォーマットされていない可能性があるためです。
適切に実行したい場合は、ArgoticやHtmlAgilityPackなどの HTML パーサーを使用することをお勧めします(どちらも NuGet で利用できます)。
それが役に立てば幸い