public class HtmlParseHelper { /// <summary> /// markdown 链接转 html a链接 /// [link](/url)转为<a class='view-more-options' href='/url'>link</a> /// </summary> /// <param name="markdownStr"></param> /// <returns></returns> public static string MarkdownLinkToHtmlALink(string markdownStr) { string result = markdownStr; try { string pattern = @"(?<!!)\[([^\]][^\[]*?)\]\((.*?)\)"; string replacement = "<a class='view-more-options' href = '$2'>$1</a>"; result = Regex.Replace(markdownStr, pattern, replacement); } catch (Exception e) { LogHelper.Error($"MarkdownLinkToHtmlALink异常:{markdownStr}", e); } return result; } }
[TestClass()] public class HtmlParseHelperTests { [TestMethod()] public void MarkdownLinkToHtmlALinkTest() { string inputStr= @"This is a [link0](/url0) This is a [link1](/url1) This is a [link2](/url2) This is a <a href='/url4'>link4</a> [查看可用选项3](/#/datasource-options?sourceName=Attendance.AttendanceMode3)"; string resutl = HtmlParseHelper.MarkdownLinkToHtmlALink(inputStr); } }
参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/substitutions-in-regular-expressions#substituting-a-numbered-group
https://c.runoob.com/front-end/854/
https://regex101.com/
案例字符串:"{"parameter":[{"name":"body","in":"body","description":"滚动时间窗查询请求参数模型","schema":{"$ref":"#/components/schemas/RequestBody_7a22bf27-37d2-4a1e-b95b-390d57b99e5e"}}],"components":{"schemas":{"Beisen.CoreHr.ESB.ServiceInterface.V5.Args.Business.EmployeeTimeWindowScrollQueryV5Args":{"title":"Beisen.CoreHr.ESB.ServiceInterface.V5.Args.Business.EmployeeTimeWindowScrollQueryV5Args","required":["StartTime","StopTime","TimeWindowQueryType","ScrollId","Capacity","startTime","stopTime"],"type":"object","properties":{"empStatus":{"title":"EmpStatus","type":"array","items":{"$ref":"#/components/schemas/Beisen.CoreHr.DomainModel.Enum.EmployeeStatus"},"description":"人员状态:默认null,示例:[2,3,7](试用、正式、返聘)。[查看可用选项](/#/datasource-options?fieldName=EmployeeStatus&metaName=TenantBase.EmploymentRecord)\n 该属性和WithDisabled互补:\n 1.若人员状态(EmpStatus)不为null且不为空集合,则使用人员状态(EmpStatus)的数值;\n 2.若人员状态(EmpStatus)为null或者空集合且是否包含离职的记录(WithDisabled)为false,则查询试用、正式、返聘状态的员工;\n 3.若人员状态(EmpStatus)为null或者空集合且是否包含离职的记录(WithDisabled)为true,则查询全部状态的员工;"},"employType":{"title":"EmployType","type":"array","items":{"$ref":"#/components/schemas/Beisen.CoreHr.DomainModel.Enum.EmployTypeEnum"},"description":"雇佣类型:默认查询内部员工。示例:[0,2],表示内部员工、实习生。 [查看可用选项](/#/datasource-options?fieldName=EmployType&metaName=TenantBase.EmploymentRecord)"},"serviceType":{"title":"ServiceType","type":"array","items":{"$ref":"#/components/schemas/Beisen.CoreHr.DomainModel.Enum.ServiceTypeEnum"},"description":"任职类型:默认查询主职。示例:[0],表示主职。[查看可用选项](/#/datasource-options?fieldName=ServiceType&metaName=TenantBase.EmploymentRecord)"},"approvalStatuses":{"title":"ApprovalStatuses","type":"array","items":{"$ref":"#/components/schemas/Beisen.CoreHr.DomainModel.Enum.ApprovalStatusEnum"},"description":"审批状态:空集合或null表示默认查询 4 生效(Effective) 的数据。可用选项包括 2 审批通过(Success)、4 审批生效(Effective),其他状态不可用, 示例:[4,2]"},"isGetLatestRecord":{"title":"IsGetLatestRecord","type":"boolean","description":"是否获取最新主职记录,默认true查询最新主职记录,为否时获取当前生效主职记录。示例:true。\n 区分最新主职记录和当前生效主职记录:当员工存在多条未删除的主职任职记录时,生效日期小于今天,失效日期大于今天的记录为当前生效的主职记录,生效日期最大的为最新主职记录"},"withDisabled":{"title":"WithDisabled","type":"boolean","description":"是否包含离职的记录,默认不包含,示例:false"},"startTime":{"title":"StartTime","type":"string","description":"时间范围开始时间,格式:2021-01-01T00:00:00","format":"date-time"},"stopTime":{"title":"StopTime","type":"string","description":"时间范围结束时间,格式:2021-01-02T00:00:00","format":"date-time"},"timeWindowQueryType":{"$ref":"#/components/schemas/Beisen.CoreHr.ESB.ServiceInterface.V5.Enum.TimeWindowQueryType"},"scrollId":{"title":"ScrollId","type":"string","description":"本批次的ScrollId,第一次查询为空,后续为上次结果返回的ScrollId。示例:\"\"或\"DXF1ZXJ5QW5kRmV0Y2gBAAAAAAVrsaUWdnVycEd3OEFRRm02aEpHRFZQZ2htdw==\"\r\n 注意:\r\n 1.scroll有过期时间限制。两次Scroll接口调用间隔不能超出10秒,可以通过while循环查出全部数据后再处理业务。\r\n 2.Scroll不能跳页,拿了第一页后要拿第三页,scroll做不到\r\n 3.Scroll不能回跳,拿了第三页之后要跳回第二页,scroll做不到"},"capacity":{"title":"Capacity","type":"integer","description":"每批次查询个数,默认100个","format":"int32","nullable":true},"sort":{"title":"Sort","type":"object","additionalProperties":{"$ref":"#/components/schemas/Beisen.MultiTenant.Model.SortDirection"},"description":"排序列名字典,Key为字段编码,Value为排序方式,多个排序条件的话,从前往后依次排序。0默认不排序、1升序、2降序。示例:{\"Name\":\"1\",\"Age\":\"2\"}"},"extQueries":{"title":"ExtQueries","type":"array","items":{"$ref":"#/components/schemas/Beisen.CoreHr.ESB.ServiceInterface.V5.DTO.ExtQuery"},"description":"自定义字段查询条件,多个条件使用and且关系,不支持or或关系。示例:[{\"fieldName\": \"extExtQueryFloat_127666_832132060\",\"queryType\": 5,\"values\": [\"1\"]}]"},"isWithDeleted":{"title":"IsWithDeleted","type":"boolean","description":"是否包括已删除数据,默认否,示例:true/false"},"columns":{"title":"Columns","type":"array","items":{"type":"string"},"description":"查询字段列表,默认null表示查询所有字段。注意:该参数仅表示是否查询该列的值,不控制响应模型的字段。示例:[\"Name\",\"Email\",\"EmployType\"]\n1.[员工信息](/#/metaobject-options?metaName=TenantBase.EmployeeInformation)\n2.[任职记录](/#/metaobject-options?metaName=TenantBase.EmploymentRecord)"},"enableTranslate":{"title":"EnableTranslate","type":"boolean","description":"是否开启动态翻译,默认否,示例:true/false。开启后,自动翻译数据源等字典类型字段,结果在响应参数的TranslateProperties中,key为对应字段加Text后缀,值为翻译后文本"}},"description":"员工相关信息滚动查询参数模型"},"Beisen.CoreHr.DomainModel.Enum.EmployeeStatus":{"enum":["None","ForEntry","OnProbation","InService","TransferredOut","TransferredIn","Retirement","Reemploy","Dimission","Die","StopReemploy","ForReemoloy","Informal"],"type":"string","oneOf":[{"const":"None"},{"const":"ForEntry"},{"const":"OnProbation"},{"const":"InService"},{"const":"TransferredOut"},{"const":"TransferredIn"},{"const":"Retirement"},{"const":"Reemploy"},{"const":"Dimission"},{"const":"Die"},{"const":"StopReemploy"},{"const":"ForReemoloy"},{"const":"Informal"}],"description":"None:\r\nForEntry:\r\nOnProbation:\r\nInService:\r\nTransferredOut:\r\nTransferredIn:\r\nRetirement:\r\nReemploy:\r\nDimission:\r\nDie:\r\nStopReemploy:\r\nForReemoloy:\r\nInformal:"},"Beisen.CoreHr.DomainModel.Enum.EmployTypeEnum":{"enum":["Inner","Other","Trainee"],"type":"string","oneOf":[{"const":"Inner"},{"const":"Other"},{"const":"Trainee"}],"description":"Inner:\r\nOther:\r\nTrainee:"},"Beisen.CoreHr.DomainModel.Enum.ServiceTypeEnum":{"enum":["MainJob","ParttimeJob","Reemploy","Loan","Expatriate"],"type":"string","oneOf":[{"const":"MainJob"},{"const":"ParttimeJob"},{"const":"Reemploy"},{"const":"Loan"},{"const":"Expatriate"}],"description":"MainJob:\r\nParttimeJob:\r\nReemploy:\r\nLoan:\r\nExpatriate:"},"Beisen.CoreHr.DomainModel.Enum.ApprovalStatusEnum":{"enum":["Draft","Approving","Success","Refused","Effective","Invalid","Rejected","Temporary"],"type":"string","oneOf":[{"const":"Draft"},{"const":"Approving"},{"const":"Success"},{"const":"Refused"},{"const":"Effective"},{"const":"Invalid"},{"const":"Rejected"},{"const":"Temporary"}],"description":"Draft:\r\nApproving:\r\nSuccess:\r\nRefused:\r\nEffective:\r\nInvalid:\r\nRejected:\r\nTemporary:"},"Beisen.CoreHr.ESB.ServiceInterface.V5.Enum.TimeWindowQueryType":{"enum":["ModifiedTime","BusinessModifiedTime"],"type":"string","oneOf":[{"description":"修改时间,系统修改同步更新该时间","const":"ModifiedTime"},{"description":"业务修改时间,系统修改不同步更新该时间","const":"BusinessModifiedTime"}],"description":"时间窗查询类型,1修改时间、2业务修改时间\nModifiedTime:修改时间,系统修改同步更新该时间。示例:\"1\"\nBusinessModifiedTime:业务修改时间,系统修改不同步更新该时间"},"Beisen.MultiTenant.Model.SortDirection":{"enum":["Default","Asc","Desc"],"type":"string","oneOf":[{"const":"Default"},{"const":"Asc"},{"const":"Desc"}],"description":"Default:\r\nAsc:\r\nDesc:"},"Beisen.CoreHr.ESB.ServiceInterface.V5.DTO.ExtQuery":{"title":"Beisen.CoreHr.ESB.ServiceInterface.V5.DTO.ExtQuery","type":"object","properties":{"fieldName":{"title":"FieldName","type":"string","description":"字段名称,示例:extExtQueryFloat_127666_832132060,严格区分大小写"},"queryType":{"$ref":"#/components/schemas/Beisen.CoreHr.ESB.ServiceInterface.V5.DTO.ExtQueryType"},"values":{"title":"Values","type":"array","items":{"type":"string"},"description":"值列表,至少包含一个元素。若条件类型为1大于、2大于等于、3小于、4小于等于时,则只能包含一个值。若条件类型为7区间,则只能包含两个值。若为等于或者不等于,可最大支持300个值,且可使用null或者空字符串进行非空或空判断。"},"includeLowerValue":{"title":"IncludeLowerValue","type":"boolean","description":"是否包含最小值,仅用于区间查询,默认true"},"includeUpperValue":{"title":"IncludeUpperValue","type":"boolean","description":"是否包含最大值,仅用于区间查询,默认true"}},"description":"查询条件"},"Beisen.CoreHr.ESB.ServiceInterface.V5.DTO.ExtQueryType":{"enum":["Larger","LargerOrEqual","Smaller","SmallerOrEqual","Equal","NotEqual","Between"],"type":"string","oneOf":[{"description":"大于","const":"Larger"},{"description":"大于等于","const":"LargerOrEqual"},{"description":"小于","const":"Smaller"},{"description":"小于等于","const":"SmallerOrEqual"},{"description":"等于","const":"Equal"},{"description":"不等于","const":"NotEqual"},{"description":"区间","const":"Between"}],"description":"自定义字段查询类型条:1大于、2大于等于、3小于、4小于等于、5等于、6不等于、7区间。仅日期时间或者数值类型支持大小比较、区间查询\r\nLarger:大于\r\nLargerOrEqual:大于等于\r\nSmaller:小于\r\nSmallerOrEqual:小于等于\r\nEqual:等于\r\nNotEqual:不等于\r\nBetween:区间"},"RequestBody_7a22bf27-37d2-4a1e-b95b-390d57b99e5e":{"$ref":"#/components/schemas/Beisen.CoreHr.ESB.ServiceInterface.V5.Args.Business.EmployeeTimeWindowScrollQueryV5Args"}}}}"
[^\]][^\[]*? 排除[ 和 ]