在嵌套括号内及其前/后Python中提取sting

时间:2017-04-03 10:14:00

标签: python algorithm brackets

我正在尝试在嵌套括号内提取字符串并生成它们。

假设我有以下字符串

string = "(A((B|C)D|E|F))"

根据Extract string inside nested brackets

中的答案

我可以在嵌套括号中提取字符串,但对于我的情况它是不同的,因为我在括号末尾有"D"所以这是代码的结果。它看起来远离我想要的输出

['B|C', 'D|E|F', 'A']

这是我想要的输出

[[['A'],['B|C'],['D']], [['A'],['E|F']']]     # '|' means OR

你有任何推荐,我应该使用正则表达式实现还是只运行所有给定的字符串?

因此它可以导致我的最终结果,即

"ABD"
"ACD"
"AE"
"AF"

在这一点上,我将使用itertools.product

2 个答案:

答案 0 :(得分:2)

您没有精确指定语言,但看起来像是允许任意嵌套括号。它不是常规语言。我不建议用正则表达式解析它(可能因为python中的正则表达式不是真正规则的,但即使它可能,它也可能是一团糟)。< / p>

我建议为您的语言定义无上下文语法并改为解析它。以下是如何做到的:

 Map<String,Double> map_2 = new LinkedHashMap<>();
 map_2 = map_1.keySet()
                .stream()
                .collect(
                        Collectors.toMap(entry -> entry, 
                                entry -> {
                                     Double value = map_1.get(entry);
                                     return (value + 5);
                                }));

这个语法可以通过一个简单的自上而下的递归解析器来解析,该解析器在线性时间内工作。这是一个示例实现:

EXPR -> A EXPR (an expression is an expression preceded by an alphabetic character)
EXPR -> (LIST) EXPR (an expression is a list followed by an expression)
EXPR -> "" (an expression can be an empty string)

LIST -> EXPR | LIST (a list is an expression followed by "|" followed by a list)
LIST -> EXPR (or just one expression)

如果您不熟悉此技术,可以阅读更多相关信息here

这个实现不是最有效的(例如,它明确地使用列表而不是迭代器),但它是一个很好的起点。

答案 1 :(得分:1)

我建议立即寻找最终结果的解决方案。所以这个函数可以进行这种转换:

Sub Monthly_Close_Daily_Report()
'
'
Dim yearMonth As String
Dim closeDay As String
Dim currTime As String
Dim summaryRange As Range
Dim completedTasks As Range
Dim incompleteTasks As Range
Dim placeholderRange As Range
Dim emailRng As Range, cl As Range
Dim lastRow As Long, x As Long
Dim sTo As String

Application.ScreenUpdating = False
Application.DisplayAlerts = False
Sheets("Inputs").Select

'Check to make sure there are no errors, then proceed
If Not IsError(Sheets("Inputs").Range("B12")) Then
    If Sheets("Inputs").Range("B12") = "Yes" Then
        'Store the YY-MM as a variable
        Sheets("Inputs").Select
        yearMonth = Range("B4").Value

        'Store the MM/DD/YYYY as a variable
        Sheets("Inputs").Select
        closeDay = Range("B5").Value

        'Store the current time as a variable
        Sheets("Inputs").Select
        currTime = Format(Now(), "h:mmAM/PM")

        'Unfilter the Task Listing tab
        Sheets("Task Listing").Select
        Range("A1").Select
        Selection.AutoFilter

        'Refresh the table with new Sharepoint data
        ActiveWorkbook.Connections("SharePoint").Refresh

            'Create a new email with the Email Listing tab in the "To" line, and Alan and Tim cc'd
            Set OutApp = CreateObject("Outlook.Application")
            Set OutMail = OutApp.CreateItem(0)

            'Determine the email addresses to send to
            Set emailRng = Worksheets("Email Listing").Range("B2:B50")
            For Each cl In emailRng
                sTo = sTo & ";" & cl.Value
            Next
            sTo = Mid(sTo, 2)

            'Set the Summary range to be copied into the email
            Set summaryRange = Sheets("Summary").Range("A1:G11")
            summaryRange.Copy

            'Filter the table for "Completed" and then add it to the placeholder tab to be converted to HTML
            Sheets.Add(After:=Worksheets(Worksheets.Count)).Name = "Placeholder"
            Range("A1").Select
            ActiveCell.FormulaR1C1 = "Completed Tasks"
            With Selection.Font
                .Name = "Arial"
                .Size = 18
                .ThemeColor = xlThemeColorLight1
            End With
            Selection.Font.Bold = True
            Sheets("Task Listing").Select
            ActiveSheet.ListObjects("Close_Tasks").Range.AutoFilter Field:=1, Criteria1:=yearMonth, Operator:=xlFilterValues
            ActiveSheet.ListObjects("Close_Tasks").Range.AutoFilter Field:=6, Criteria1 _
                :="Completed"
            ActiveSheet.UsedRange.Select
            Selection.SpecialCells(xlCellTypeVisible).Select
            Selection.Copy
            Sheets("Placeholder").Select
            Range("A3").Select
            ActiveSheet.Paste

            'Find the last row of the "Placeholder" sheet
            lastRow = Cells(Rows.Count, 1).End(xlUp).Row

            'Copy the format to the "Incomplete" section header
            Range("A1").Select
            Selection.Copy
            Range("A" & lastRow + 3).Select
            ActiveSheet.Paste
            ActiveCell.FormulaR1C1 = "Incomplete Tasks"

            'Filter the table for "Incomplete" and then add it to the placeholder tab to be converted to HTML
            Sheets("Task Listing").Select
            ActiveSheet.ListObjects("Close_Tasks").Range.AutoFilter Field:=6, Criteria1 _
                :="=In Progress", Operator:=xlOr, Criteria2:="=Not Started"
            ActiveSheet.UsedRange.Select
            Selection.SpecialCells(xlCellTypeVisible).Select
            Selection.Copy
            Sheets("Placeholder").Select

            'Find the new last row of the "Placeholder" tab
            lastRow = Cells(Rows.Count, 1).End(xlUp).Row

            'Paste the incomplete tasks to the "Placeholder" tab
            Range("A" & lastRow + 1).Select
            ActiveSheet.Paste

            'Format the "Placeholder" tab
            Cells.Select
            With Selection
                .WrapText = False
                .Orientation = 0
                .AddIndent = False
                .IndentLevel = 0
                .ShrinkToFit = False
                .ReadingOrder = xlContext
                .MergeCells = False
            End With
            Cells.EntireColumn.AutoFit

            'Find the new last row of the "Placeholder" tab
            lastRow = Cells(Rows.Count, 1).End(xlUp).Row

            'Make the entire "Placeholder" sheet the placeholderRange
            Set placeholderRange = Range("A1:G" & lastRow)

            'On Error Resume Next
            With OutMail
                .To = sTo
                .CC = ""
                .BCC = ""
                .Subject = "Month End Close Status for " & yearMonth & " As Of " & currTime & " on " & closeDay
                '.HTMLBody = RangetoHTML(summaryRange) & "<br><br><strong>Completed Tasks" & RangetoHTML(completedTasks) & "<br><br><strong>Incomplete Tasks" & RangetoHTML(incompleteTasks)
                .HTMLBody = RangetoHTML(summaryRange) & "<br><br>" & RangetoHTML(placeholderRange)
                .Display 'Can also use .Send which will send the email.  We want to preview before sending, though.
            End With

            Set OutMail = Nothing
            Set OutApp = Nothing

    Else
        'If tasks are missing Due Dates, flag those for the user and exit the macro
        MsgBox ("There are ""Due Dates"" missing for some tasks.  Please correct the issue and run the macro again.")
    End If

End If

    'Delete the Placeholder tab
    Sheets("Placeholder").Delete

    'Filter the "Task Listing" tab for the current month
    Sheets("Task Listing").Select
    Range("A2").Select
    Selection.AutoFilter
    ActiveSheet.ListObjects("Close_Tasks").Range.AutoFilter Field:=1, Criteria1:=yearMonth, Operator:=xlFilterValues

Application.ScreenUpdating = True
Application.DisplayAlerts = True

'
End Sub

以下是我建议的代码:

input: "(A((B|C)D|E|F))"
output: ['ABD', 'ACD', 'AE', 'AF']

repl.it

上查看它