C# 判断中文、日文和韩文

在 C# 中,我们可以使用正则表达式来判断字符串是否包含特定的字符集。本文将展示如何使用正则表达式来判断字符串是否为中文、日文或韩文。

1. 正则表达式简介

  • 中文字符:匹配 Unicode 范围为 \u4e00-\u9fa5 的字符。
  • 日文字符:匹配 Unicode 范围为 \u3040-\u309F(平假名)、\u30A0-\u30FF(片假名)、\u4E00-\u9FFF(常用汉字)。
  • 韩文字符:匹配 Unicode 范围为 \uac00-\ud7ff 的字符。

2. 匹配东亚语言

如果要匹配所有东亚语言(包括中文、日文和韩文),可以使用如下的正则表达式:

// language: csharp
@"[\u4E00-\u9fa5\u3040-\u309F\u30A0-\u30FF\uac00-\ud7ff]"

该正则表达式能够匹配中文、日文和韩文字符,但如果你希望对不同语言进行分类,则需要具体判断。

3. 判断韩文

要判断字符串是否为韩文,可以使用以下代码:

// language: csharp
if(System.Text.RegularExpressions.Regex.IsMatch(content, @"^[\uac00-\ud7ff]+$"))
{
    // 如果是韩文
}

该正则表达式会检查字符串是否仅包含韩文字符。

4. 判断日文

判断字符串是否为日文,代码如下:

// language: csharp
if(System.Text.RegularExpressions.Regex.IsMatch(content, @"^[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]+$"))
{
    // 如果是日文
}

该正则表达式会检查字符串是否仅包含日文字符。

5. 判断中文

判断字符串是否为中文字符,可以使用以下代码:

// language: csharp
if (System.Text.RegularExpressions.Regex.IsMatch(content, @"^[\u4e00-\u9fa5]+$"))
{
    // 如果是中文
}

该正则表达式会检查字符串是否仅包含中文字符。

6. 示例应用

通过结合正则表达式,我们可以很方便地在 C# 中进行不同语言的文本检测。以下是完整示例代码:

// language: csharp
using System;
using System.Text.RegularExpressions;

public class LanguageDetection
{
    public static void Main(string[] args)
    {
        string content = "这是一个测试内容";

        // 判断是否为中文
        if (Regex.IsMatch(content, @"^[\u4e00-\u9fa5]+$"))
        {
            Console.WriteLine("这是中文");
        }
        // 判断是否为日文
        else if (Regex.IsMatch(content, @"^[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]+$"))
        {
            Console.WriteLine("这是日文");
        }
        // 判断是否为韩文
        else if (Regex.IsMatch(content, @"^[\uac00-\ud7ff]+$"))
        {
            Console.WriteLine("这是韩文");
        }
        else
        {
            Console.WriteLine("无法识别的语言");
        }
    }
}

这段代码会根据内容的语言输出相应的结果。

.NET中如何使用PhantomJS与Selenium模拟采集数据

在现代 web 开发中,数据采集是一个非常常见的需求。无论是从网站中提取信息,还是进行自动化测试,模拟用户行为都变得尤为重要。在 .NET 环境中,常见的两种模拟采集的工具是 PhantomJS 和 Selenium。这两者各具特点,适用于不同的场景。本文将介绍这两款工具及其如何在 .NET 中使用。

1. PhantomJS——无头浏览器的利器

什么是 PhantomJS?

PhantomJS 是一个无头浏览器(headless browser),意味着它没有图形界面,完全通过命令行操作。它可以模拟浏览器行为,执行网页中的 JavaScript 代码,获取渲染后的网页内容,并支持截图、页面交互等操作。由于它不需要图形界面,运行效率比普通浏览器更高,尤其适用于大规模的网页抓取和自动化测试。

PhantomJS 在数据采集中的应用

PhantomJS 非常适合用来进行 网页抓取,特别是当页面内容通过 JavaScript 动态生成时。很多现代网站的数据展示依赖于 JavaScript 渲染,传统的 HTML 解析工具(如 HtmlAgilityPack)在这种情况下无法直接提取数据,而 PhantomJS 可以通过模拟浏览器,渲染页面并抓取其中的数据。

在 .NET 中使用 PhantomJS

虽然 PhantomJS 自身是用 JavaScript 编写的,但我们可以通过使用外部库来在 .NET 中调用 PhantomJS。一个常用的库是 PhantomJS.Net,它提供了 .NET 与 PhantomJS 的接口,使得在 .NET 中模拟浏览器变得更加方便。

使用 PhantomJS.NET 的示例代码:

// language: csharp
using System;
using PhantomJS.Net;

class Program
{
    static void Main()
    {
        var driver = new PhantomJSDriver();
        driver.Navigate().GoToUrl("https://example.com");

        // 获取渲染后的网页内容
        var pageSource = driver.PageSource;
        Console.WriteLine(pageSource);

        driver.Quit();
    }
}

在这个示例中,我们首先初始化了一个 PhantomJS 驱动器,加载了目标网页,然后获取了渲染后的 HTML 内容。

2. Selenium——强大的自动化测试工具

什么是 Selenium?

Selenium 是一款广泛使用的自动化测试工具,支持多种编程语言(包括 C#、Java、Python 等)。它不仅可以用来模拟浏览器行为,还支持模拟用户操作,如点击、输入、滚动等。Selenium 支持所有现代浏览器,包括 Chrome、Firefox 和 Safari 等,除了无头浏览器模式(headless mode)外,它还支持在有图形界面的环境下操作浏览器。

Selenium 在数据采集中的应用

Selenium 可以模拟真实的用户行为,因此非常适合 交互式数据采集。例如,你需要登录网站、填写表单、点击按钮来获取数据时,Selenium 是一个理想的选择。而且它支持 JavaScript 执行,因此可以抓取动态加载的网页内容。

在 .NET 中使用 Selenium

在 .NET 环境中使用 Selenium 需要安装相应的 NuGet 包。常见的库有 Selenium.WebDriver 和 Selenium.WebDriver.ChromeDriver,这些包可以通过 NuGet 安装。

使用 Selenium 的示例代码:

// language: csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;

class Program
{
    static void Main()
    {
        // 设置 Chrome 驱动器
        var options = new ChromeOptions();
        options.AddArgument("headless"); // 无头模式

        var driver = new ChromeDriver(options);
        driver.Navigate().GoToUrl("https://example.com");

        // 获取渲染后的网页内容
        var pageSource = driver.PageSource;
        Console.WriteLine(pageSource);

        driver.Quit();
    }
}

这个示例展示了如何通过 Selenium 在无头模式下启动 Chrome 浏览器,加载目标网页,并获取渲染后的 HTML 内容。

3. PhantomJS 与 Selenium 的对比

虽然 PhantomJS 和 Selenium 都可以用来模拟采集,但它们有一些显著的区别:

特性PhantomJSSelenium
浏览器类型无头浏览器 (Headless Browser)可以支持有头和无头浏览器
性能高效,启动速度快,适合大规模抓取启动速度稍慢,但更强大、灵活
JavaScript 支持完全支持 JavaScript完全支持 JavaScript
支持的浏览器仅 PhantomJS支持所有主要浏览器(Chrome, Firefox, Safari)
适用场景爬虫和抓取静态页面自动化测试和交互式爬虫

从对比表格中可以看出,PhantomJS 更适合于快速的网页抓取,尤其是当你只需要获取页面内容而不需要模拟用户交互时。而 Selenium 更适合需要复杂交互的场景,如登录、填写表单、点击按钮等。

4. 总结

PhantomJS 和 Selenium 都是强大的工具,能够帮助开发者在 .NET 中模拟浏览器行为进行数据采集。选择哪个工具取决于你的需求:

  • 如果你需要快速抓取页面并且不需要复杂的用户交互,PhantomJS 是一个不错的选择。
  • 如果你需要模拟更复杂的用户行为(如填写表单、点击按钮等),Selenium 会更为适合。

无论你选择哪个工具,正确使用它们将能帮助你高效地进行数据采集工作。

ASP.NET Core 中如何获取 Unix 时间戳

在 ASP.NET Core 中,我们可以通过 DateTimeOffset 类型来获取当前时间的 Unix 时间戳。DateTimeOffset 代表一个带有时区偏移量的日期和时间,它提供了比 DateTime 更强大的时区支持。要获取当前时间的 Unix 时间戳,可以使用 ToUnixTimeSeconds 方法。

需要注意的是,此方法从 .NET Core 2.0 开始提供。

1. 获取当前时间的 Unix 时间戳

// language: csharp
using System;

public class Program
{
    public static void Main()
    {
        // 获取当前时间的 Unix 时间戳(秒级)
        long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
        Console.WriteLine("当前时间的 Unix 时间戳为: " + timestamp);
    }
}

2. 获取 UTC 时间的 Unix 时间戳

如果你需要获取 UTC 时间的 Unix 时间戳,可以使用 DateTimeOffset.UtcNow,它返回的是 UTC(协调世界时)时间。

// language: csharp
using System;

public class Program
{
    public static void Main()
    {
        // 获取当前 UTC 时间的 Unix 时间戳(秒级)
        long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
        Console.WriteLine("当前 UTC 时间的 Unix 时间戳为: " + timestamp);
    }
}

C#数据库连接类

在使用ado.net连接数据库时,我们需要自己创建数据库连接类,目的是为了方便对数据库连接进行管理和方便使用。下面的Db类用于创建并打开一个数据库连接。

这个类也可以搭配Dapper使用,当使用Dapper时,我们也需要这样的一个类,使用使用conn来调用Dapper中的一些扩展方法用于快速操作数据库。

public class Db
{
	private static string connectionString = "Data Source=.;Initial Catalog=Minsu;User Id=sa;Password=123456;Encrypt=False;TrustServerCertificate=False;";

	public static SqlConnection GetConnection()
	{
		SqlConnection conn = new SqlConnection(connectionString);
		conn.Open();
		return conn;
	}
}

这个类在使用时,记得要放在using中使用,以避免资源泄露。例如下面的代码:

using(var conn = Db.GetConnection()) 
{
    // 数据库操作...
}

解决 ASP.NET Core 连接 SQL Server 时“证书链由不受信任的颁发机构颁发”错误

使用基于.NET 8的ASP.NET Core连接sql server数据库时,遇到报错:sql server 证书链是由不受信任 的颁发机构颁发的

解决办法是,在数据库连接串上增加TrustServerCertificate=False;,即改为下面的形式就可以了:

// language: csharp
Data Source=.;Initial Catalog=WorkSummary;User Id=sa;Password=123456;Encrypt=False;TrustServerCertificate=False;

EntityFramework DbFirst

EntityFramework这个.NET 的 ORM框架,可以代码优先(code first),也可以数据库优先(database first),本文主要介绍数据库优先 database first 的使用方法:

先在Package Manager Console中安装 Microsoft.EntityFrameworkCore.Tools包:

Install-Package Microsoft.EntityFrameworkCore.Tools

然后使用下面的命令扫描数据库,该命令根据数据库连接串扫描数据库,并生成相应的模型类。

Scaffold-DbContext "Server=127.0.0.1;User ID=root;Password=123456;Database=worksummary_net;" Pomelo.EntityFrameworkCore.MySql -OutputDir Data\Entities

扫描完成后,就可以在项目中使用EF进行数据库操作了。

C# 字典Dictionary.Add(key, value) 与 Dictionary[key]=value的区别

相同:

二者都是根据键值(key),在字典中添加新元素(value)的方法

不同:

Dictionary.Add(key, value) 方法,如果 Dictionary 中已经有了这个 key ,那么在进行 Add 会在运行时报错;

Dictionary[key]=value 方法,如果 Dictionary 中已经有了这个key ,新添加的value将替换之前的 value ,即没有时添加,有时则修改替换

因此,在使用时更加倾向使用 Dictionary[key]=value 方法,可以减少出错,但是使用时也要注意键值是否正确对应。

asp.net core 解析 easyui的tree的json

easyui的tree组件支持从JSON加载数据,在asp.net中,我们可以从数据库读取相关数据,然后转换成json格式后返回给easyui的tree组件。下面是具体过程:

1、定义相关的节点类

public class PermissionTreeNode
{
    public int id { get; set; }
    public string? text { get; set; }
    public string? state { get; set; }
    public bool @checked { get; set; }
    public PermissionTreeNode[]? children { get; set; }
}

public class Permission
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public Role? Role { get;set; }
    public DateTime? CreatedAt { get; set; } = DateTime.Now;
    public DateTime? UpdatedAt { get; set; } = DateTime.Now;
}

public class Role 
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public ICollection<Permission>? Permissions { get; set; }
    public ICollection<Account>? Accounts { get; set; }
    public DateTime? CreatedAt { get; set; } = DateTime.Now;
    public DateTime? UpdatedAt { get; set; } = DateTime.Now;
}

2、编写生成节点的函数 ParseJson,在这个函数里面加了权限处理,只添加当前用户有权限的节点:

public PermissionTreeNode ParseJson(PermissionTreeNode permissionTreeNode, List<Permission> rolePermissions, Role role)
{
    if (permissionTreeNode.children != null)
    {
        foreach (var menu in permissionTreeNode.children)
        {
            if (rolePermissions.Any(x => x.Name == menu.text) || role.Name == "超级管理员")
            {
                menu.@checked = true;
            }

            if (menu.children != null)
            {
                ParseJson(menu, rolePermissions, role);
            }
        }
    }

    return permissionTreeNode;
}

3、最后,我们在初始化tree的数据的时候,调用InitPermissionTree函数生成节点数据,再通过JsonSerializer.Serialize函数转换成json格式,不要忘记在转换后的json字符串两边分别加上[和],不然easyui的tree组件加载不了。

public ContentResult InitPermissionTree(int roleId)
{
    var rolePermissions = _appDbContext.Permissions.Where(x => x.Role != null && x.Role.Id == roleId).ToList();

    var role = _appDbContext.Roles.Where(x => x.Id == roleId).FirstOrDefault();

    var jsonFile = Path.Combine(_env.WebRootPath, $"PermissionTree.json");
    var json = System.IO.File.ReadAllText(jsonFile);


    JsonSerializerOptions options = new JsonSerializerOptions();
    options.ReferenceHandler = default;
    var permissionTreeNode = JsonSerializer.Deserialize<PermissionTreeNode>(json, options);

    if (permissionTreeNode != null && role != null)
    {
        permissionTreeNode = ParseJson(permissionTreeNode, rolePermissions, role);
    }

    var result = "[" + JsonSerializer.Serialize(permissionTreeNode) + "]";

    return Content(result, "application/json");
}

我们可以使用F12浏览器开发者工具查看接口返回的JSON,如下:

  {
    "id": 1,
    "text": "工作总结生成管理系统",
    "checked": false,
    "children": [
      {
        "id": 100,
        "text": "内容管理",
        "state": "open",
        "checked": false,
        "children": [
          {
            "id": 101,
            "text": "文章管理",
            "checked": false,
            "children": [
              {
                "id": 102,
                "text": "文章生成",
                "checked": false
              },
              {
                "id": 103,
                "text": "编辑文章",
                "checked": false
              },
              {
                "id": 104,
                "text": "删除文章",
                "checked": false
              },
              {
                "id": 105,
                "text": "状态设置",
                "checked": false
              },
              {
                "id": 106,
                "text": "导出Word文档(文章管理)",
                "checked": false
              }
            ]
          },
          {
            "id": 200,
            "text": "素材库",
            "state": "opened",
            "checked": false,
            "children": [
              {
                "id": 201,
                "text": "新增素材",
                "checked": false
              },
              {
                "id": 202,
                "text": "编辑素材",
                "checked": false
              },
              {
                "id": 203,
                "text": "删除素材",
                "checked": false
              },
              {
                "id": 204,
                "text": "导入导出",
                "checked": false
              },
              {
                "id": 205,
                "text": "素材审核",
                "checked": false
              }
            ]
          },
          {
            "id": 300,
            "text": "标签库",
            "state": "opened",
            "checked": false,
            "children": [
              {
                "id": 301,
                "text": "创建标签",
                "checked": false
              },
              {
                "id": 302,
                "text": "编辑标签",
                "checked": false
              },
              {
                "id": 303,
                "text": "删除标签",
                "checked": false
              }
            ]
          },

          {
            "id": 400,
            "text": "模板库",
            "state": "opened",
            "checked": false,
            "children": [
              {
                "id": 401,
                "text": "新增模板",
                "checked": false
              },
              {
                "id": 402,
                "text": "编辑模板",
                "checked": false
              },
              {
                "id": 403,
                "text": "删除模板",
                "checked": false
              }
            ]
          },

          {
            "id": 500,
            "text": "档案库",
            "state": "opened",
            "checked": false,
            "children": [
              {
                "id": 501,
                "text": "删除档案",
                "checked": false
              },
              {
                "id": 502,
                "text": "查看档案",
                "checked": false
              },
              {
                "id": 503,
                "text": "导入Word文档",
                "checked": false
              },
              {
                "id": 504,
                "text": "导出Word文档(档案库)",
                "checked": false
              },
              {
                "id": 505,
                "text": "移到文章管理",
                "checked": false
              }
            ]
          }
        ]
      },
      {
        "id": 600,
        "text": "系统设置",
        "state": "open",
        "checked": false,
        "children": [
          {
            "id": 601,
            "text": "帐号管理",
            "state": "open",
            "checked": false,
            "children": [
              {
                "id": 602,
                "text": "新增帐号",
                "checked": false
              },
              {
                "id": 603,
                "text": "编辑帐号",
                "checked": false
              },
              {
                "id": 604,
                "text": "删除帐号",
                "checked": false
              },
              {
                "id": 605,
                "text": "重置密码",
                "checked": false
              }
            ]
          },
          {
            "id": 700,
            "text": "部门管理",
            "state": "open",
            "checked": false,
            "children": [
              {
                "id": 701,
                "text": "新增部门",
                "checked": false
              },
              {
                "id": 702,
                "text": "编辑部门",
                "checked": false
              },
              {
                "id": 703,
                "text": "删除部门",
                "checked": false
              }
            ]
          },
          {
            "id": 800,
            "text": "角色管理",
            "state": "open",
            "checked": false,
            "children": [
              {
                "id": 801,
                "text": "新增角色",
                "checked": false
              },
              {
                "id": 802,
                "text": "编辑角色",
                "checked": false
              },
              {
                "id": 803,
                "text": "删除角色",
                "checked": false
              }
            ]
          }

        ]
      }
    ]
  }

这样,asp.net core 给 easyui 的 tree 组件动态生成数据就完成了。

.NET Core 读取系统环境变量

asp.net core 的开发过程中,有时会需要读取系统的环境,可以使用下面的代码来读取:

var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", EnvironmentVariableTarget.Machine);

注意 EnvironmentVariableTarget.Machine 只能读取“系统变量”里配置的环境变量

注意:该方法只在windows上测试通过,linux系统没有测试,有试过的同学可以留个言。